本人第一次写CDQ,常数有点大,TLE只有60pts,求改进(或指出不正确的写法)。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,k,ans[300003],ans2[300003],k1,k2,k3,k4,k5,k6,k7;
struct Flw{
int val[3];
char mk[3];
int num;
}F[300003],stk[3][300003];
int tot;
int sum[300003];
bool comp(Flw X,Flw Y){
if(X.val[0]!=Y.val[0])return X.val[0]<Y.val[0];
if(X.val[1]!=Y.val[1])return X.val[1]<Y.val[1];
if(X.val[2]!=Y.val[2])return X.val[2]<Y.val[2];
return X.num<Y.num;
}
void cdq(int dms,int l,int r){
if(l==r)return;
cdq(dms,l,((l+r)>>1));cdq(dms,((l+r)>>1)+1,r);
for(int i=l;i<=r;i++)F[i].mk[dms]=(i>((l+r)>>1));
tot=0;
k1=l;
k2=((l+r)>>1)+1;
k4=((l+r)>>1);
while(1){
while(k1<=k4&&F[k1].val[dms]<=F[k2].val[dms])stk[dms][++tot]=F[k1++];
if(k1>k4)break;
while(k2<=r&&F[k2].val[dms]<F[k1].val[dms])stk[dms][++tot]=F[k2++];
if(k2>r)break;
}
while(k1<=k4)stk[dms][++tot]=F[k1++];
while(k2<=r)stk[dms][++tot]=F[k2++];
for(int i=l;i<=r;i++)F[i]=stk[dms][i-l+1];
if(dms!=2){
cdq(dms+1,l,r);
for(int i=l;i<=r;i++)F[i]=stk[dms][i-l+1];
}
else{
k3=0;
for(int i=l;i<=r;i++){
if(F[i].mk[0]==0&&F[i].mk[1]==0&&F[i].mk[2]==0)k3++;
if(F[i].mk[0]&&F[i].mk[1]&&F[i].mk[2])ans[F[i].num]+=k3;
}
}
return;
}
signed main(){
scanf("%lld%lld",&n,&k);
for(int i=1;i<=n;i++)scanf("%lld%lld%lld",&F[i].val[0],&F[i].val[1],&F[i].val[2]);
sort(F+1,F+n+1,comp);
for(int i=1;i<=n;i++)F[i].num=i;
k1=n;
for(int i=n;i>0;i--){
if(F[i].val[0]!=F[k1].val[0]||F[i].val[1]!=F[k1].val[1]||F[i].val[2]!=F[k1].val[2])k1=i;
ans[i]+=(k1-i);
}
for(int i=1;i<=n;i++){
F[i].val[0]*=200000;
F[i].val[0]+=i;
F[i].val[1]*=200000;
F[i].val[1]+=i;
F[i].val[2]*=200000;
F[i].val[2]+=i;
}
cdq(0,1,n);
for(int i=1;i<=n;i++)ans2[ans[i]]++;
for(int i=0;i<n;i++)printf("%lld\n",ans2[i]);
return 0;
}