陌上花开

Posted hikigaya

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了陌上花开相关的知识,希望对你有一定的参考价值。

心态崩了,又因为打错了一个字母调了1个半小时

CDQ分治,一维排序,二维分治,三维树状数组

注意去重,以及对答案的处理

树状数组维护值域真方便

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7;
int n,k,c[N],nn,cnt[N];
struct node{
    int a,b,c,ans=0,sz=0;
}a[N],b[N];
void add(int x,int y){
    while(x<=k){
        c[x]+=y;
        x+=x&-x;
    }
}
int ask(int x){
    int anss=0;
    while(x){
        anss+=c[x];
        x-=x&-x;
    }
    return anss;
}
bool cmpa(node x,node y){
    return x.a==y.a?(x.b==y.b?x.c<y.c:x.b<y.b):x.a<y.a;
}
bool cmpb(node x,node y){
    return x.b==y.b?x.c<y.c:x.b<y.b;
}
void cdq(int L,int R){
    if(L==R)return;
    int mid=L+R>>1;
    cdq(L,mid);
    cdq(mid+1,R);
    int l=L,r=mid+1;
    sort(a+L,a+mid+1,cmpb);
    sort(a+mid+1,a+R+1,cmpb);
    while(r<=R){
        while(a[l].b<=a[r].b&&l<=mid){
            add(a[l].c,a[l].sz);
            ++l;
        }
        a[r].ans+=ask(a[r].c);
        r++;
    }
    for(int i=l-1;i>=L;i--){
        add(a[i].c,-a[i].sz);(把i打成了l我也是佛了)
    }
}
int main(){
    cin>>nn>>k;
    for(int i=1;i<=nn;i++)
        scanf("%d%d%d",&b[i].a,&b[i].b,&b[i].c);
    sort(b+1,b+1+nn,cmpa);
    int sz=0;
    for(int i=1;i<=nn;i++){
        sz++;
        if(b[i].a!=b[i+1].a||b[i].b!=b[i+1].b||b[i].c!=b[i+1].c)
            a[++n]=b[i],a[n].sz=sz,sz=0;
    }
    cdq(1,n);
    for(int i=1;i<=n;i++)
        cnt[a[i].ans+a[i].sz-1]+=a[i].sz;
    for(int i=0;i<nn;i++)
        printf("%d
",cnt[i]);
    return 0;
}

 

以上是关于陌上花开的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 3262: 陌上花开

BZOJ3262陌上花开

luogu模板三维偏序(陌上花开)

[luogu3810][bzoj3262][陌上花开]

P3810 模板三维偏序(陌上花开)(cdq分治)

陌上花开