题目链接<https://cn.vjudge.net/problem/HYSBZ-3262>
题解:
一共有三维:一维排序,一维CDQ,一维树状数组。
每一次CDQ分治都需要清空数组。
注意:数值一样的花会互相影响,可以去重,然后加一个权重来处理。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+7;
const int M=2e5+7;
int n,k;
struct Node{
int x,y,z,cnt,val;
bool operator<(const Node a)const{
if(x==a.x&&y==a.y) return z<a.z;
if(x==a.x) return y<a.y;
return x<a.x;
}
bool operator==(const Node a)const{
return x==a.x&&y==a.y&&z==a.z;
}
}a[N],b[N];
int ans[N];
int c[M];
int ask(int x){
int res=0;
for(int i=x;i;i-=i&(-i)){
res+=c[i];
}
return res;
}
void add(int x,int val){
for(int i=x;i<=k;i+=i&(-i)){
c[i]+=val;
}
}
void cdq(int l,int r){
if(l==r) return;
int m=l+r>>1;
cdq(l,m);cdq(m+1,r);
int p=l,q=m+1,i=l;
while(p<=m&&q<=r){
if(a[p].y<=a[q].y){
add(a[p].z,a[p].val);
b[i++]=a[p++];
}
else{
a[q].cnt+=ask(a[q].z);
b[i++]=a[q++];
}
}
while(p<=m){
add(a[p].z,a[p].val);
b[i++]=a[p++];
}
while(q<=r){
a[q].cnt+=ask(a[q].z);
b[i++]=a[q++];
}
for(int i=l;i<=m;i++) add(a[i].z,-a[i].val);
for(int i=l;i<=r;i++) a[i]=b[i];
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
a[i].cnt=0;a[i].val=1;
}
sort(a+1,a+1+n);
int tot=1;
for(int i=2;i<=n;i++){
if(a[i]==a[i-1]) a[tot].cnt++,a[tot].val++;
else a[++tot]=a[i];
}
cdq(1,tot);
for(int i=1;i<=tot;i++){
ans[a[i].cnt]+=a[i].val;
}
for(int i=0;i<n;i++) printf("%d\n",ans[i]);
}