题解:裸cdq分治
一开始处理相同花的时候搞错了,WA了几发
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=200009; int n,m; int b[maxn],nn; int fsiz; int ans[maxn],f[maxn]; int x[maxn],y[maxn],z[maxn],w[maxn]; int c[maxn]; inline int lowbit(int x){ return x&(-x); } void Addp(int x,int val){ while(x<=nn){ c[x]+=val; x+=lowbit(x); } } int Querysum(int x){ int ret=0; while(x){ ret+=c[x]; x-=lowbit(x); } return ret; } void Cle(int x){ while(x<=nn){ c[x]=0; x+=lowbit(x); } } struct Flower{ int p; bool operator < (const Flower &rhs) const{ if(x[p]<x[rhs.p])return 1; if(x[p]>x[rhs.p])return 0; if(y[p]<y[rhs.p])return 1; if(y[p]>y[rhs.p])return 0; return z[p]<z[rhs.p]; } bool operator == (const Flower &rhs) const{ return x[p]==x[rhs.p]&&y[p]==y[rhs.p]&&z[p]==z[rhs.p]; } }a[maxn]; int cmpy(const Flower &rhs1,const Flower &rhs2){ if(y[rhs1.p]==y[rhs2.p])return z[rhs1.p]<z[rhs2.p]; else return y[rhs1.p]<y[rhs2.p]; } void Cdq(int l,int r){ if(l==r)return; int mid=(l+r)>>1; int t1=l,t2=mid+1; sort(a+l,a+mid+1,cmpy); sort(a+mid+1,a+r+1,cmpy); while(t2<=r){ while((t1<=mid)&&(y[a[t1].p]<=y[a[t2].p])){ Addp(z[a[t1].p],w[a[t1].p]);++t1; } f[a[t2].p]+=Querysum(z[a[t2].p]); ++t2; } for(int i=l;i<=mid;++i)Cle(z[a[i].p]); sort(a+l,a+r+1); 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",&x[i],&y[i],&z[i]); for(int i=1;i<=n;++i)a[i].p=i; sort(a+1,a+1+n); fsiz=unique(a+1,a+1+n)-a-1; for(int i=1;i<=n;++i)b[i]=z[i]; sort(b+1,b+1+n); nn=unique(b+1,b+1+n)-b-1; for(int i=1;i<=n;++i)z[i]=lower_bound(b+1,b+1+nn,z[i])-b; for(int i=1;i<=n;++i){ a[n+1].p=i; int p=lower_bound(a+1,a+1+fsiz,a[n+1])-a; w[a[p].p]++; } Cdq(1,fsiz); sort(a+1,a+1+fsiz); for(int i=1;i<=n;++i){ a[n+1].p=i; int p=lower_bound(a+1,a+1+fsiz,a[n+1])-a; ans[f[a[p].p]+w[a[p].p]-1]++; } for(int i=0;i<n;++i)printf("%d\n",ans[i]); return 0; }