https://www.lydsy.com/JudgeOnline/problem.php?id=3262

题意:n朵花,每朵花有3个属性a,b,c,一朵花比另一朵花美丽当且仅当3个属性都大于等于另一朵,一朵花比x朵花美丽则称其等级为x,求出每个等级的花的数量。
思路:三维偏序问题,cdq分治模板
https://zhuanlan.zhihu.com/p/55322598这个讲解不错。

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) (x&(-x))
#define maxn 200000+100
 
int n,k,c[maxn],cnt,ans[maxn];
struct Element{
    int a,b,c,w,f;
    bool operator < (Element x)const{
        if(a!=x.a)return a<x.a;
        if(b!=x.b)return b<x.b;
        return c<x.c; 
    }
}e[maxn],t[maxn];
 
int sum(int x)
{
    int ret=0;
    while(x)
    {
        ret+=c[x];
        x-=lowbit(x);
    }
    return ret;
}
 
void add(int x,int d)
{
    while(x<=k)
    {
        c[x]+=d;
        x+=lowbit(x);
    }
}
 
void CDQ(int l,int r)
{   
    if(l==r)return;
    int mid=(l+r)/2;
    CDQ(l,mid);     
    CDQ(mid+1,r);       
    int p=l,q=mid+1,x=l;
    while(p<=mid || q<=r)
    {
        if(q>r || p<=mid && e[p].b<=e[q].b)add(e[p].c,e[p].w),t[x++]=e[p++];
        else e[q].f+=sum(e[q].c),t[x++]=e[q++];//这里切记两句不可颠倒,因为前一句对e[q]有改动。
    }
    for(x=l;x<=mid;x++)add(e[x].c,-e[x].w);
    for(x=l;x<=r;x++)e[x]=t[x];
}
 
int main()
{
    //freopen("input.in","r",stdin);
    cin>>n>>k;
    for(int i=1;i<=n;i++)scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].c),e[i].w=1;
    sort(e+1,e+1+n);
    for(int i=1;i<=n;i++)
    {
        if(e[i].a==e[cnt].a&&e[i].b==e[cnt].b&&e[i].c==e[cnt].c)e[cnt].w++;
        else e[++cnt]=e[i];
    }   
    CDQ(1,cnt);
    for(int i=1;i<=cnt;i++)ans[e[i].f+e[i].w-1]+=e[i].w;
    for(int i=0;i<n;i++)printf("%d\n",ans[i]);
    return 0;
}