题解:裸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;
}