Link
Solve
CDQ分治的模板题,第一维直接排序,第二位用递归,第三位用树状数组
实在不懂的小伙伴戳这里浅谈CDQ分治
Code
#include<bits/stdc++.h>
using namespace std;
int N,ans[1000005],K,c[200005],m;
struct AS{
int a,b,c,cnt,ans;
}a[100005],b[100005];
inline int read(){
int ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
bool cmp1(AS A,AS B){return (A.a<B.a)||(A.a==B.a&&A.b<B.b)||(A.a==B.a&&A.b==B.b&&A.c<B.c);}
bool cmp2(AS A,AS B){return (A.b<B.b)||(A.b==B.b&&A.c<B.c);}
void add_x(int x,int data){
for(int i=x;i<=K;i+=i&-i)c[i]+=data;
return ;
}
int get(int x){
int S=0;
for(int i=x;i;i-=i&-i)S+=c[i];
return S;
}
void CDQ(int l,int r){
if(l==r)return ;
int mid=(r-l>>1)+l;
CDQ(l,mid);CDQ(mid+1,r);
sort(b+l,b+mid+1,cmp2);
sort(b+mid+1,b+r+1,cmp2);
int i,j=l;
for(i=mid+1;i<=r;i++){
while(b[i].b>=b[j].b&&j<=mid){
add_x(b[j].c,b[j].cnt);
j++;
}
b[i].ans+=get(b[i].c);
}
for(int i=l;i<j;i++)add_x(b[i].c,-b[i].cnt);
}
int main(){
freopen("CDQ.in","r",stdin);
freopen("CDQ.out","w",stdout);
N=read();K=read();
for(int i=1;i<=N;i++)a[i].a=read(),a[i].b=read(),a[i].c=read();
sort(a+1,a+1+N,cmp1);
for(int i=1;i<=N;i++){
if(a[i].a==a[i-1].a&&a[i].b==a[i-1].b&&a[i].c==a[i-1].c){b[m].cnt++;continue;}
m++;b[m].a=a[i].a;b[m].b=a[i].b;b[m].c=a[i].c;b[m].cnt++;
}
CDQ(1,m);
for(int i=1;i<=m;i++)ans[b[i].ans+b[i].cnt-1]+=b[i].cnt;
for(int i=0;i<N;i++)printf("%d
",ans[i]);
return 0;
}