第一个线段树。。。线段树真是灵活多变啊。。。看来要好好掌握还要多加练习。。
- /*pku2352
- Name: Stars
- Date: 02-08-08 16:41
- Description: 统计问题,线段树
- */
- #include<stdio.h>
- #define MAX 72010
- #define pr printf
- // FILE * pp=fopen("temp.txt","w");
- struct node{
- int count;//被覆盖过的次数
- int l,r;
- }nodes[MAX];
- void build(int l,int r,int step){
- int mid;
- nodes[step].r=r;
- nodes[step].l=l;
- nodes[step].count=0;
- if(r-l>1){
- mid=(r+l)/2;
- build(l,mid,step*2);//l
- build(mid,r,step*2+1);//r
- }
- }
- void insert(int l,int r,int step){
- nodes[step].count++;
- int r0=nodes[step].r,l0=nodes[step].l;
- if(l==l0 && r==r0)return ;
- int mid=(r0+l0)/2;
- if(mid<=l)insert(l,r,step*2+1);
- else if(mid>=r) insert(l,r,step*2);
- else insert(mid,r,step*2+1); //线段跨越节点时,插入节点的右子树
- //新插入的点其实只有r,所以只要在右子树插入就可以了
- }
- int query(int l,int r,int step){
- int r0=nodes[step].r,l0=nodes[step].l;
- if(l==l0 && r==r0){
- return nodes[step].count;
- }
- int mid=(l0+r0)/2;
- if(mid<=l)return query(l,r,step*2+1);//在右子树上
- if(mid>=r)return query(l,r,step*2);//左子树
- return query(l,mid,step*2)+query(mid,r,step*2+1);
- }
- int ans[15003];
- int main(){
- int n,i,x,y;
- scanf("%d",&n);
- for(i=0;i<n;i++)ans[i]=0;
- build(0,32000,1);
- for(i=0;i<n;i++)
- {
- scanf("%d%d",&x,&y);
- ans[query(0,x,1)]++;
- insert(0,x,1);
- }
- for(i=0;i<n;i++)
- pr("%d/n",ans[i]);
- scanf("%d",&i);
- }