#include<iostream> #include<cstdio> #include<algorithm> using namespace std; #define N 300000 int n,m,xb,head[N],nxt[N],f[N],ans[N],bit[N],cnt[N]; struct point{ int x,y,z,num,i,ID; bool operator < (const point n) const{ return x<n.x || (x==n.x && y<n.y) || (x==n.x && y==n.y && z<n.z); } bool operator != (const point n) const{ return x!=n.x || y!=n.y || z!=n.z; } }a[N],b[N],tmp[N]; bool cmp(point n,point m){ return n.y<m.y || (n.y==m.y && n.z<m.z) || (n.y==m.y && n.z==m.z && n.x<m.x); } void add(int x,int val){ for (int i=x;i<=m;i+=i&(-i)) bit[i]+=val; } int query(int x){ int sum=0; for (int i=x;i;i-=i&(-i)) sum+=bit[i]; return sum; } void cdq(int l,int r){ if (l==r) return; int mid=(l+r)>>1,xb1=l,xb2=mid+1; sort(b+l,b+r+1,cmp); for (int i=l;i<=r;i++){ if (b[i].ID<=mid) add(b[i].z,b[i].num); if (b[i].ID>mid) ans[b[i].ID]+=query(b[i].z); } for (int i=l;i<=r;i++) if (b[i].ID<=mid) add(b[i].z,-b[i].num); for (int i=l;i<=r;i++) if (b[i].ID<=mid) tmp[xb1++]=b[i]; else tmp[xb2++]=b[i]; for (int i=l;i<=r;i++) b[i]=tmp[i]; cdq(l,mid); cdq(mid+1,r); } int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;i++){scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z); a[i].i=i;} sort(a+1,a+n+1); for (int i=1;i<=n;i++) if (a[i]!=a[i-1]){b[++xb]=a[i]; head[xb]=a[i].i; b[xb].num=1;} else{nxt[a[i].i]=head[xb]; head[xb]=a[i].i; b[xb].num++;} sort(b+1,b+xb+1); for (int i=1;i<=xb;i++){b[i].ID=i; ans[i]=b[i].num-1;} cdq(1,xb); for (int i=1;i<=xb;i++) for (int j=head[i];j;j=nxt[j]) f[j]=ans[i]; for (int i=1;i<=n;i++) cnt[f[i]]++; for (int i=0;i<n;i++) printf("%d\n",cnt[i]); return 0; }
|