zoukankan      html  css  js  c++  java
  • [CDQ分治]三维偏序

    题目链接

    Code

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    
    #define RG register int
    #define LL long long
    
    template<typename elemType>
    inline void Read(elemType &T){
        elemType X=0,w=0; char ch=0;
        while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
        while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        T=(w?-X:X);
    }
    
    const int maxn=100010;
    inline int lowbit(int x){return x&(-x);}
    
    struct BIT{
        int Node[300010];
        int N;
        void set_Len(int len){N=len;}
        void Update(int x,int Add){for(;x<=N;x+=lowbit(x)) Node[x]+=Add;}
        int PrefixSum(int x){int Res=0;for(;x;x-=lowbit(x)) Res+=Node[x];return Res;}
    };
    BIT Tree;
    
    struct Point{int a,b,c;};
    Point Data[maxn];
    int ID[maxn],Count[maxn],temp[maxn],Cnt[maxn],Ans[maxn];
    int N,K,top;
    
    bool cmp(int x,int y){
        if(Data[x].a==Data[y].a){
            if(Data[x].b==Data[y].b) return Data[x].c<Data[y].c;
            return Data[x].b<Data[y].b;
        }
        return Data[x].a<Data[y].a;
    }
    
    void CDQ(int *id,int n){
        if(n==1) return;
        int mid=n>>1;
        CDQ(id,mid);
        CDQ(id+mid,n-mid);
        memcpy(temp+1,id+1,n*sizeof(int));
        RG k=1,i=1,j=mid+1;
        for(;i<=mid && j<=n;++k){
            int x=temp[i],y=temp[j];
            if(Data[x].b<=Data[y].b){Tree.Update(Data[id[k]=x].c,Count[x]);++i;}
            else{Cnt[y]+=Tree.PrefixSum(Data[id[k]=y].c);++j;}
        }
        --k;
        for(;j<=n;++j){
            Cnt[temp[j]]+=Tree.PrefixSum(Data[temp[j]].c);
            id[++k]=temp[j];
        }
        for(RG l=i-1;l>=1;--l)
            Tree.Update(Data[temp[l]].c,-Count[temp[l]]);
        for(;i<=mid;++i) id[++k]=temp[i];
        return;
    }
    
    void Unique(){
        sort(ID+1,ID+N+1,cmp);
        top=1;Count[ID[top]]=1;
        for(RG i=2;i<=N;++i){
            int x=ID[i],y=ID[top];
            if(Data[x].a^Data[y].a||Data[x].b^Data[y].b||Data[x].c^Data[y].c){
                ID[++top]=x;++Count[x];}
            else ++Count[ID[top]];
        }
        return;
    }
    
    int main(){
        Read(N);Read(K);
        Tree.set_Len(K);
        for(RG i=1;i<=N;++i){
            ID[i]=i;
            Read(Data[i].a);
            Read(Data[i].b);
            Read(Data[i].c);
        }
        Unique();
        CDQ(ID,top);
        for(RG i=1;i<=top;++i)
            Ans[Cnt[ID[i]]+Count[ID[i]]-1]+=Count[ID[i]];
        for(RG i=0;i<N;++i)
            printf("%d
    ",Ans[i]);
        
        return 0;
    }
    
  • 相关阅读:
    弹窗
    [转]JNI字段描述符“([Ljava/lang/String;)V”
    [转]JNIEnv解析
    [转]"error while loading shared libraries: xxx.so.x" 错误的原因和解决办法
    [转]Linux下如何查看版本信息
    [转]apt-get 与 yum的区别 (转)
    我的tesseract学习记录(二)
    [转]pkg-config的用法
    [转]linux 创建连接命令 ln -s 软链接
    如何写makefile
  • 原文地址:https://www.cnblogs.com/AEMShana/p/12950410.html
Copyright © 2011-2022 走看看