第一次用指针写线段树,以前都是用数组写的。这道算是入门的线段树了。感觉用指针写,代码看起来更有艺术感,更优雅。对了,纪念下,这代码是一次AC的。
#include <stdio.h>
#include <stdlib.h>
#define MAX 99999999
struct cnode
{
int left;
int right;
int Min;
int Max;
struct cnode* pleft;
struct cnode* pright;
}*root;
void build(int s,int t,struct cnode* node)//建立线段树
{
node->left = s;
node->right = t;
node->Min = MAX;
node->Max = -MAX;
if(s == t)
{
node->pleft = NULL;
node->pright = NULL;
return;
}
node->pleft = (struct cnode*)malloc(sizeof(struct cnode));
build(s,(s+t)>>1,node->pleft);
node->pright = (struct cnode*)malloc(sizeof(struct cnode));
build(((s+t)>>1)+1,t,node->pright);
}
void RMQ(int s,int t,int pos,int value,struct cnode* node)//建立RMQ的性质的线段树
{
if(value > (node->Max))
{
(node->Max) = value;
}
if(value < node->Min)
{
node->Min=value;
}
if(node->pleft == NULL&&node->pright == NULL)
{
return;
}
if(node->pleft->left <= pos && node->pleft->right >= pos)
{
RMQ(s,(s+t)>>1,pos,value,node->pleft);
}
else if(node->pright->left <= pos && node->pright->right >= pos)
{
RMQ(((s+t)>>1)+1,t,pos,value,node->pright);
}
}
int AnsMin;
int AnsMax;
void query(int s,int t,int qs,int qt,struct cnode* node)//往跟[s,t]有交集的地方递归下去,如果找到的区间是[s,t]的真子集,就停止递归下去(即返回)
{
if((qs <= node->left) && (qt >= node->right))
{
if(node->Max > AnsMax)
{
AnsMax =node->Max;
}
if(node->Min < AnsMin)
{
AnsMin = node->Min;
}
return;
}
int mid = (s+t)>>1;
if(qs <= mid && qt > mid)
{
query(s,mid,qs,qt,node->pleft);
query(mid+1,t,qs,qt,node->pright);
}
else if(mid >= qt)
{
query(s,mid,qs,qt,node->pleft);
}
else if(mid < qs)
{
query(mid+1,t,qs,qt,node->pright);
}
}
int main()
{
int n,m;
int i;
int value;
int s,t;
while(scanf("%d %d",&n,&m) != EOF)
{
root=(struct cnode*)malloc(sizeof(struct cnode));
struct cnode* node = (struct cnode*)malloc(sizeof(struct cnode));
root=node;
build(1,n,node);
for(i=1;i<=n;i++)
{
scanf("%d",&value);
RMQ(1,n,i,value,node);
}
for(i=0;i<m;i++)
{
scanf("%d %d",&s,&t);
AnsMin=MAX;
AnsMax=-MAX;
query(1,n,s,t,node);
printf("%d\n",AnsMax-AnsMin);
}
}
return 0;
}

1509

被折叠的 条评论
为什么被折叠?



