Description
Input
Output
Sample Input
5 1 1 5 1 7 1 3 3 5 5
Sample Output
1 2 1 1 0
题目大意: 有n个星星, 现在分别给出它们按y递增的坐标,每个星星有一个等级(该星星的等级是x坐标和y坐标都不大于该星的星星数),先要求出每个等级的星星有多少个
这个是线段树第一次写,详解请关注大神博客:
http://blog.csdn.net/ulquiorra0cifer/article/details/7769675
LANGUAGE:C
CODE:
#include<stdio.h> #include<string.h> #define max 33000 struct { int l,r,sum; }tree[max<<2]; void build(int l,int r,int idx) { int mid=(l+r)>>1;//get the midle tree[idx].sum=0;//init sum if(l==r)//at same point { tree[idx].l=tree[idx].r=r; return ; } tree[idx].l=l;tree[idx].r=r; build(l,mid,idx<<1);//build left subtree build(mid+1,r,idx<<1|1);//build(mid+1,r,idx*2+1);build right subtree } void add(int l,int r,int idx) { int mid=(tree[idx].l+tree[idx].r)>>1; if(tree[idx].l==l&&tree[idx].r==r)//if find the segment { tree[idx].sum++;//current segement return ; } if(l>mid) add(l,r,idx<<1|1);//if the segement at root's right:add to the right subtree else if(r<=mid)add(l,r,idx<<1);//if the segement at root's left:add to the left subtree else { add(l,mid,idx<<1);//add to the left subtree add(mid+1,r,idx<<1|1);//add to the right subtree } tree[idx].sum=tree[idx<<1|1].sum+tree[idx<<1].sum;//get sum } int query(int l,int r,int idx) { int mid=(tree[idx].l+tree[idx].r)>>1; if(tree[idx].l==l&&tree[idx].r==r)//if find the segement,return sum; return tree[idx].sum; if(l>mid) return query(l,r,idx<<1|1);//return right subtree's sum; else if(r<=mid) return query(l,r,idx<<1);//return left subtree's sum; else return query(l,mid,idx<<1)+query(mid+1,r,idx<<1|1);//return the sum of subtree's sum; } int main() { int i,n,x,y,lev[max]; while(scanf("%d",&n)!=EOF) { memset(lev,0,sizeof(lev)); build(0,max,1); for(i=0;i<n;i++) { scanf("%d%d",&x,&y); lev[query(0,x,1)]++; add(x,x,1); } for(i=0;i<n;i++) printf("%d\n",lev[i]); } return 0; }