一维排序;
二维CDQ;
三维BIT。
LuoguP3810
先上代码,代码还是蛮长的
事实上可以免去
//1D
............
cdq(1,num);
中间的............
然而有重复。。。
struct point
{
int a,b,c,cnt,ans;
}g[100010];
int n,m,ans[100010],bit[10000010],num;
bool cmp2(point x,point y)
{
if(x.b==y.b)
rt x.c<y.c;
rt x.b<y.b;
}
bool cmp1(point x,point y)
{
if(x.a==y.a)
rt cmp2(x,y);
rt x.a<y.a;
}
void add(int x,int y)
{
while(x<=m)
{
bit[x]+=y;
x+=x&(-x);
}
}
int query(int x)
{
int r=0;
while(x)
{
r+=bit[x];
x-=x&(-x);
}
rt r;
}
void cdq(int l,int r)
{
if(l==r)
rt;
int mid=(l+r)>>1;
cdq(l,mid);
cdq(mid+1,r);
sort(g+l,g+mid+1,cmp2);
sort(g+mid+1,g+r+1,cmp2);//2D
int t1=l,t2=mid+1;
while(t2<=r)
{
while(t1<=mid&&g[t1].b<=g[t2].b)
{
add(g[t1].c,g[t1].cnt);
t1++;
}
g[t2].ans+=query(g[t2].c);
t2++;
}
fr(i,l,t1-1)
add(g[i].c,-g[i].cnt);//3D
}
int main()
{
n=read();
m=read();
fr(i,1,n)
g[i].a=read(),g[i].b=read(),g[i].c=read(),g[i].cnt=1;
sort(g+1,g+n+1,cmp1);//1D
fr(i,1,n)
{
int k=i+1;
while(g[i].a==g[k].a&&g[i].b==g[k].b&&g[i].c==g[k].c)
k++;
num++;
k--;
g[i].cnt+=k-i;
g[num]=g[i];
i=k;
}
cdq(1,num);
fr(i,1,num)
ans[g[i].ans+g[i].cnt-1]+=g[i].cnt;
fr(i,0,n-1)
printf("%d\n",ans[i]);
rt 0;
}