线段树经典入门题,线段树本弱是一个半月前听的课,没练题,今天第一次做线段树,一个半小时。。。。
这道题由于数据给出是按y递增的,所以难度降低了,否则应该是先根据y大小由小到大来排序。刚开始我不知道要维护那些数据,翻了一下当时的课件,才渐渐理解只需记录元素个数。。。。tree数组要比maxn大两倍(理论上好像是,一般直接三倍)
#include <stdio.h>
#include <string.h>
int level[15001],N,tree[96000];
int x[32001];
void Buildtree(int tn,int left,int right,int x)
{
int mid;
if(left==right) {tree[tn]++; return;}
mid=(left+right)>>1;
if(mid>=x)
Buildtree(tn<<1,left,mid,x);
else Buildtree(tn<<1|1,mid+1,right,x);
tree[tn]=tree[tn<<1]+tree[tn<<1|1];
}
int Find(int tn,int left,int right,int x)
{
int mid;
if(left==right) return tree[tn];
mid=(left+right)>>1;
if(mid>=x) return Find(tn<<1,left,mid,x);
else return tree[tn<<1]+Find(tn<<1|1,mid+1,right,x);
}
int main(int argc, char const *argv[])
{
int i,tmpx,tmpy;
scanf("%d",&N);
memset(level,0,15001*sizeof(int));/*没有这个也可以,因为是在函数外开的,初始值也是0*/
memset(tree,0,96000*sizeof(int));
for(i=0;i<N;i++)
{
scanf("%d %d",&tmpx,&tmpy);
Buildtree(1,0,32000,tmpx);
level[Find(1,0,32000,tmpx)-1]++;
}
for(i=0;i<N;i++)
printf("%d\n",level[i] );
return 0;
}