标签:树状数组
Description
Input
Output
Sample Input
3 1 2 0 3 3 4 0
Sample Output
1 0 0
这题的做法和star那道题差不多,先按x坐标进行升序排列,然后x相同的取对y进行降序排列,排好后记录一个pos值,表示循环到i这个位置时最早和当前i的线段一样的线段的编号,然后分情况讨论,看当前线段是否和a[pos]一样,不一样就更新pos,直接算出前面线段包含当前线段的条数i-getsum(a[i].y),如果一样的话还要再减去i-pos。
#include<iostream> #include<stdio.h> #include<string.h> #include<math.h> #include<vector> #include<map> #include<queue> #include<stack> #include<string> #include<algorithm> using namespace std; #define maxn 100006 int b[maxn]; struct node{ int x,y,id,num; }a[maxn]; bool cmp(node a,node b){ int temp; if(a.x==b.x){ return a.y>b.y; } return a.x<b.x; } bool cmp1(node a,node b){ return a.id<b.id; } int lowbit(int x){ return x&(-x); } void update(int pos,int num) { while(pos<=maxn){ b[pos]+=num;pos+=lowbit(pos); } } int getsum(int x) { int num=0; while(x>0){ num+=b[x];x-=lowbit(x); } return num; } int main() { int n,m,i,j,pos; while(scanf("%d",&n)!=EOF && n!=0) { for(i=1;i<=n;i++){ scanf("%d%d",&a[i].x,&a[i].y); a[i].x++;a[i].y++; a[i].id=i; } memset(b,0,sizeof(b)); sort(a+1,a+1+n,cmp); pos=0; for(i=1;i<=n;i++){ if(i==1){ pos=1;a[i].num=0;update(a[i].y,1); continue; } if(a[i].x==a[pos].x && a[i].y==a[pos].y){ a[i].num=i-1-getsum(a[i].y-1)-(i-pos); update(a[i].y,1); } else{ pos=i; a[i].num=i-1-getsum(a[i].y-1); update(a[i].y,1); } } sort(a+1,a+1+n,cmp1); for(i=1;i<=n;i++){ if(i==n)printf("%d\n",a[i].num); else printf("%d ",a[i].num); } } return 0; }
标签:树状数组
原文地址:http://blog.csdn.net/kirito_acmer/article/details/46350091