题意:
在x,y坐标系下有N(N<=15000)个星星...一个星星的等级是x,y(x,y<=32767)坐标都不超过它的星星个数..现在问0~N-1个等级各有多少个星星..
题解:
和POJ2481差不多..甚至要方便很多..因为不是输出每个星星的信息..只是统计..所以没必要对线段记录原始位置了..又题意保证不会出现相同的点..所以不用来维护相同的点..排好序..直接用树状数组搞就是...比较恶心的是..直接用y坐标作为树状数组的下标会超时..但y坐标比N要少..所以离散化后..170ms就AC了..
Program:
#include<iostream> #include<stdio.h> #include<string.h> #include<queue> #include<stack> #include<algorithm> #include<cmath> #include<set> #include<map> #include<time.h> #define ll long long #define oo 1000000009 #define MAXN 15000 #define pi acos(-1.0) #define esp 1e-30 #define MAXD 4 using namespace std; struct node { int x,y; }L[MAXN]; int N,sum[MAXN+2],ans[MAXN+2],Y[MAXN+2]; bool cmp(node a,node b) { if (a.x!=b.x) return a.x<b.x; return a.y<b.y; } void update(int x,int k) { while (k<=N) { sum[k]+=x; k+=k&(-k); } } int query(int k) { int ans=0; while (k) { ans+=sum[k]; k-=k&(-k); } return ans; } int bsearch(int y) { int l=0,r=N+1,mid; while (r-l>1) { mid=r+l>>1; if (Y[mid]>y) r=mid; else l=mid; } return l; } int main() { int i,y; scanf("%d",&N); for (i=1;i<=N;i++) scanf("%d%d",&L[i].x,&L[i].y),Y[i]=L[i].y; sort(L+1,L+1+N,cmp),sort(Y+1,Y+1+N); memset(sum,0,sizeof(sum)); memset(ans,0,sizeof(ans)); for (i=1;i<=N;i++) { y=bsearch(L[i].y); ans[query(y)]++,update(1,y); } for (i=0;i<N;i++) printf("%d\n",ans[i]); return 0; }