1. 程式人生 > 其它 >CDQ分治(三維偏序集)

CDQ分治(三維偏序集)

排序,三關鍵字

去重

歸併排序+樹狀陣列

#include<bits/stdc++.h>
using namespace std;
#define re register int
const int N=100010;
const int M=200010;
int n,m;
struct node{
    int a,b,c,s,res;
    bool operator < (node y) const {
        if(a==y.a&&b==y.b)return c<y.c;
        if(a==y.a)return b<y.b;
        
return a<y.a; } bool operator == (node y) const { return a==y.a&&b==y.b&&c==y.c; } }q[N],w[N];int cnt; int tr[M+100],ans[N]; void ins(int x,int v){ for(re i=x;i<M;i+=(i&(-i)))tr[i]+=v; } int query(int x){ int ret=0; for(re i=x;i;i-=(i&(-i)))ret+=tr[i];
return ret; } void merge_sort(int l,int r){ if(l>=r)return ; int mid=l+r>>1; merge_sort(l,mid); merge_sort(mid+1,r); int i=l,j=mid+1,k=l; while(i<=mid&&j<=r){ if(q[i].b<=q[j].b)ins(q[i].c,q[i].s),w[k++]=q[i++]; else q[j].res+=query(q[j].c),w[k++]=q[j++]; }
while(i<=mid)ins(q[i].c,q[i].s),w[k++]=q[i++]; while(j<=r)q[j].res+=query(q[j].c),w[k++]=q[j++]; for(i=l;i<=mid;i++)ins(q[i].c,-q[i].s); //for(i=1;i<=M;i++)if(tr[i]==0)cout<<tr[i]<<endl; for(i=l;i<=r;i++)q[i]=w[i]; } signed main(){ scanf("%d%d",&n,&m); for(re i=1;i<=n;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); q[i]={a,b,c,1}; } sort(q+1,q+n+1); for(re i=1;i<=n;i++){ //cout<<q[i].a<<" "<<q[i].b<<" "<<q[i].c<<" "<<q[i].s<<endl; if(q[i]==q[i-1])q[cnt].s++; else q[++cnt]=q[i]; } /*for(re i=1;i<=cnt;i++){ cout<<q[i].a<<" "<<q[i].b<<" "<<q[i].c<<" "<<q[i].s<<endl; }*/ merge_sort(1,cnt); for(re i=1;i<=cnt;i++){ //cout<<q[i].a<<" "<<q[i].b<<" "<<q[i].c<<" "<<q[i].s<<" "<<q[i].res<<endl; ans[q[i].res+q[i].s-1]+=q[i].s; } for(re i=0;i<n;i++)printf("%d\n",ans[i]); }