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 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++;
}
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;
}