poj 3264 Balanced Lineup——简单线段树

这是我的第一道线段树呀吼吼~~~~~虽然这道题很简单,但是我写的时候还是犯了很多错误,RE了几次,还是属于没有理解线段树到底是怎么分段的。。。

把自己的代码对着标改把改把过了,发现跑了3000+MS,怎么这么慢,然后我就去网上找了很多大神的线段树代码拿来交,发现都是3000+MS,才知道原来还有更好的做法,比如ST什么的。。。

用数组模拟整个线段树,要求开由于N即为线段树最底层的节点数,则线段树最高为(ceil)log2 N+1=17层;则线段树最多有2^17-1个节点=131071 ,所以开了150000~~

a27400 3264 Accepted 2428K 3375MS G++ 1635B 2011-10-05 11:49:45
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAX 1000000+10
#define MIN -1

using namespace std;

struct node
{
int l;
int r;
int max;
int min;
}tree[150000+10];
int mx,mn;

void buildtree(int indx,int start,int end)
{
tree[indx].l=start;
tree[indx].r=end;
tree[indx].max=MIN;
tree[indx].min=MAX;
if(start==end)
return;
int mid=(start+end)/2;
buildtree(indx*2,start,mid);
buildtree(indx*2+1,mid+1,end);//先开始没理解,写的mid,结果在本机上就RE了。。。
return;
}

void insert(int indx,int i,int value)
{
if(tree[indx].l==tree[indx].r)
{
tree[indx].max=value;
tree[indx].min=value;
return;
}
tree[indx].max=max(tree[indx].max,value);//随时更新它父亲节点的max,min
tree[indx].min=min(tree[indx].min,value);
int mid=(tree[indx].l+tree[indx].r)/2;
if(mid>=i)
insert(indx*2,i,value);
else insert(indx*2+1,i,value);
}

void query(int indx,int start,int end)
{
if(tree[indx].min>=mn&&tree[indx].max<=mx)
return;
if(start==tree[indx].l&&end==tree[indx].r)
{
mx=max(tree[indx].max,mx);
mn=min(tree[indx].min,mn);
return;
}
int mid=(tree[indx].l+tree[indx].r)/2;
if(end<=mid)//注意判断顺序!!
query(indx*2,start,end);
else if(start>mid)//多写一个等号导致交上去RE。。以后要注意了
query(indx*2+1,start,end);
else
{
query(indx*2,start,mid);
query(indx*2+1,mid+1,end);
}
}

int main(void)
{
int N,Q;
scanf("%d %d",&N,&Q);
int i;
buildtree(1,1,N);
for(i=1;i<=N;i++)
{
int a;
scanf("%d",&a);
insert(1,i,a);
}
for(i=1;i<=Q;i++)
{
int start,end;
scanf("%d %d",&start,&end);
mx=MIN;//这个别写反了
mn=MAX;
query(1,start,end);
printf("%d\n",mx-mn);
}
return 0;
}



你可能感兴趣的:(poj)