cdq做三维偏序。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 500500 #define maxw 500500 using namespace std; int m,w,t[maxn],n=0,cnt=0,ans[maxn]; struct pnt { int a,b,c,s,ans; }p[maxn],q[maxn]; bool cmp1(pnt x,pnt y) { if ((x.a==y.a) && (x.b==y.b)) return x.c<y.c; else if (x.a==y.a) return x.b<y.b; return x.a<y.a; } bool cmp2(pnt x,pnt y) { if (x.b==y.b) return x.c<y.c; return x.b<y.b; } int lowbit(int x) { return (x&(-x)); } void update(int x,int val) { for (int i=x;i<=w;i+=lowbit(i)) t[i]+=val; } int ask(int x) { int ret=0; for (int i=x;i>=1;i-=lowbit(i)) ret+=t[i]; return ret; } void cdq(int left,int right) { if (left==right) return; int mid=left+right>>1; cdq(left,mid);cdq(mid+1,right); sort(q+left,q+mid+1,cmp2);sort(q+mid+1,q+right+1,cmp2); int i=left,j=mid+1; while (j<=right) { while ((i<=mid) && (q[i].b<=q[j].b)) { update(q[i].c,q[i].s); i++; } q[j].ans+=ask(q[j].c); j++; } for (int j=left;j<i;j++) update(q[j].c,-q[j].s); } int main() { scanf("%d%d",&m,&w); for (int i=1;i<=m;i++) scanf("%d%d%d",&p[i].a,&p[i].b,&p[i].c); sort(p+1,p+m+1,cmp1); for (int i=1;i<=m;i++) { cnt++; if ((p[i].a!=p[i+1].a) || (p[i].b!=p[i+1].b) || (p[i].c!=p[i+1].c)) { q[++n]=p[i]; q[n].s=cnt; cnt=0; } } cdq(1,n); for (int i=1;i<=n;i++) ans[q[i].ans+q[i].s-1]+=q[i].s; for (int i=0;i<m;i++) printf("%d\n",ans[i]); return 0; }