Jam like to solve the problem which on the 3D-axis,given N(1<=N<=100000) points (x,y,z)(1<=x,y,z<=100000)
If two point such as (xi,yi,zi) and (xj,yj,zj) xi>=xj,yi>=yj,zi>=zj,the bigger one level add 1.
Ask for the each level of the point.
Input
The first line is T(1<=T<=15) means T Case
For each case
The first line is N means the number of Point and next there are N line, each line has (x,y,z)
Output
Output with N line,each line has one number means the lever of point
Sample Input
扫描二维码关注公众号,回复:
1005384 查看本文章
1 4 10 4 7 10 6 6 8 2 5 7 3 10
Sample Output
1 1 0 0
代码:
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> using namespace std; const int maxn = 100005; int n; struct node { int x,y,z,ans,number;//ans表示比自己小的点得个数,number是输入时顺序编号。 }p[maxn]; bool cmpx(node a,node b) { if(a.x!=b.x)return a.x<b.x; if(a.y!=b.y)return a.y<b.y; return a.z<b.z; } bool cmpy(node a,node b) { if(a.y!=b.y)return a.y<b.y; return a.z<b.z; } bool cmpn(node a,node b) { return a.number < b.number; } struct BIT //树状数组 { #define lowbit(x) (x&(-x)) int b[maxn]; void init() { memset(b,0,sizeof(b)); } void update(int x,int v) { while(x<=maxn) { b[x]+=v; x+=lowbit(x); } } int query(int x) { int ans=0; while(x) { ans+=b[x]; x-=lowbit(x); } return ans; } void clear(int x) { while(x<=maxn) { b[x]=0; x+=lowbit(x); } } }bit; void CDQ(int l,int r) { if(l==r) { return ; } int mid = l + (r-l)/2; CDQ(l,mid); CDQ(mid+1,r); sort(p+l,p+mid+1,cmpy); sort(p+mid+1,p+r+1,cmpy); int j=l; for(int i=mid+1;i<=r;i++) { for(;j<=mid&&p[j].y<=p[i].y;j++) bit.update(p[j].z,1); p[i].ans += bit.query(p[i].z); } for(int i=l;i<j;i++)bit.update(p[i].z,-1);//把加入的值再去掉。 } int main() { int T; scanf("%d",&T); while(T--){ bit.init(); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].z),p[i].ans=0,p[i].number = i; sort(p+1,p+n+1,cmpx); CDQ(1,n); for(int i = 1;i <= n;)//处理重复点,因为如果有重复点那么其中肯定有一些重复点(x1,y1,z1)==(x2,y2,z2)的情况没算上。 { int j = i + 1; int tmp = p[i].ans; for(;j <= n && p[i].x == p[j].x && p[i].y == p[j].y && p[i].z == p[j].z ;++ j)tmp = max(tmp,p[j].ans); for(int k = i;k < j;k ++)p[k].ans = tmp; i = j; } sort(p+1,p+1+n,cmpn);//恢复初始顺序 for(int i=1;i<=n;i++)printf("%d\n",p[i].ans); } return 0; }