CDQ板子

三维偏序

#include<bits/stdc++.h>
using namespace std;
const int maxn=100004;
int n,m,k,c[maxn<<1],num[maxn];
struct node{
    int x,y,z,w,ans;
}a[maxn],b[maxn];
inline bool cmpx(node p,node q){
    if(p.x==q.x){
        if(p.y==q.y) return p.z<q.z;
        return p.y<q.y;
    }
    return p.x<q.x;
}
inline bool cmpy(node p,node q){
    if(p.y==q.y) return p.z<q.z;
    return p.y<q.y;
}
inline int lowbit(int x) {return x&-x;}
inline void add(int x,int y){
    while(x<=k){
        c[x]+=y;
        x+=lowbit(x);
    }
}
inline int ask(int x){
    int sum=0;
    while(x){
        sum+=c[x];
        x-=lowbit(x);
    }
    return sum;
}
inline void cdq(int l,int r){
    if(l==r) return;
    int mid=(l+r)>>1;
    cdq(l,mid);cdq(mid+1,r);
    sort(a+l,a+mid+1,cmpy);
    sort(a+mid+1,a+r+1,cmpy);
    int j=l;
    for(int i=mid+1;i<=r;i++){
        while(a[j].y<=a[i].y&&j<=mid) add(a[j].z,a[j].w),j++;
        a[i].ans+=ask(a[i].z);
    }
    for(int i=l;i<j;i++){
        add(a[i].z,-a[i].w);
    }
}
int main(){
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++) scanf("%d%d%d",&b[i].x,&b[i].y,&b[i].z);
    sort(b+1,b+n+1,cmpx);
    int d=0;
    for(int i=1;i<=n;i++){
        d++;
        if(b[i].x!=b[i+1].x||b[i].y!=b[i+1].y||b[i].z!=b[i+1].z){
            a[++m]=b[i],a[m].w=d,d=0;
        }
    }
    cdq(1,m);
    for(int i=1;i<=m;i++){
        num[a[i].ans+a[i].w-1]+=a[i].w;
        //cout<<a[i].ans<<' '<<a[i].w<<endl;
    }
    for(int i=0;i<n;i++){
        printf("%d\n",num[i]);
    }
    return 0;
}

 

posted @ 2019-01-15 11:32  WiFiMonster  阅读(148)  评论(0编辑  收藏  举报