题意:有
n
n
n个元素,第
i
i
i个元素有
a
i
,
b
i
,
c
i
a_i,b_i,c_i
ai,bi,ci三个属性,设
f
i
f_i
fi表示满足
a
i
≥
a
j
,
b
i
≥
b
j
,
c
i
≥
c
j
a_i\geq a_j,b_i\geq b_j,c_i\geq c_j
ai≥aj,bi≥bj,ci≥cj的
j
j
j的数量。对于
d
∈
[
0
,
n
)
d\in [0, n)
d∈[0,n),求
f
i
=
d
f_i=d
fi=d的数量。
考虑
c
d
q
cdq
cdq分治,静态排序消除一维,然后就可以用
c
d
q
cdq
cdq消除一维,最后一维有许多的做法,详细介绍一下再套一个
c
d
q
cdq
cdq的。
其实
c
d
q
cdq
cdq可以一直套,只要记录一下每一层这个数是否有能力产生贡献。
也就是说,在上一层
c
d
q
cdq
cdq中,归为右边的数记它的权值为
1
1
1,只有权值为
1
1
1的数,才能在下一层
c
d
q
cdq
cdq中产生影响和计算答案。
c
o
d
e
:
code:
code:
#include <bits/stdc++.h>
#define regi register int
int n,k;
int ans[1000000];
int pts[1000000];
struct axe{
int x;
int y;
int z;
int id;
int val;
int amount;
}a[1000000],b[1000000],c[1000000],tmp[1000000];
bool cmp(axe x,axe y){
return x.x==y.x?(x.y==y.y?x.z<y.z:x.y<y.y):x.x<y.x;
}
void calc(int l,int r){
if(l==r)
return;
int mid=l+r>>1;
calc(l,mid);
calc(mid+1,r);
int C=0;
for(regi top=l,i=l,j=mid+1;top<=r;++top){
if((j>r||b[i].z<=b[j].z)&&i<=mid){
c[top]=b[i++];
C+=c[top].val*c[top].amount;
}
else{
c[top]=b[j++];
if(!c[top].val)
ans[c[top].id]+=C;
}
}
for(regi i=l;i<=r;++i)
b[i]=c[i];
}
void solve(int l,int r){
if(l==r)
return;
int mid=l+r>>1;
solve(l,mid);
solve(mid+1,r);
for(regi top=l,i=l,j=mid+1;top<=r;++top){
if((j>r||a[i].y<=a[j].y)&&i<=mid){
b[top]=a[i++];
b[top].val=1;
}
else{
b[top]=a[j++];
b[top].val=0;
}
}
for(regi i=l;i<=r;++i)
a[i]=b[i];
calc(l,r);
}
main(){
scanf("%d%d",&n,&k);
for(regi i=1;i<=n;++i){
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
a[i].id=i;
}
std::sort(a+1,a+n+1,cmp);
tmp[1]=a[1];
tmp[1].amount=1;
int j=1;
for(regi i=2;i<=n;++i){
if(a[i].x!=tmp[j].x||a[i].y!=tmp[j].y||a[i].z!=tmp[j].z)
tmp[++j]=a[i];
tmp[j].amount++;
}
int nn=n;
n=j;
for(regi i=1;i<=n;++i)
a[i]=tmp[i];
solve(1,n);
for(regi i=1;i<=n;++i)
pts[ans[a[i].id]+a[i].amount]+=a[i].amount;
for(regi i=1;i<=nn;++i)
printf("%d\n",pts[i]);
return 0;
}