zoukankan      html  css  js  c++  java
  • [洛谷 P3834] 可持久化线段树模板

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    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 INF=2147483647;
    const int MAXN=200010;
    vector<int> HashData;
    int Data[MAXN];
    int N,M,ElemNum;
    
    inline void Discretization(){
        HashData[0]=-INF;
        sort(HashData.begin(),HashData.end());
        HashData.erase(unique(HashData.begin(),HashData.end()),HashData.end());
        ElemNum=HashData.size()-1;
        return;
    }
    
    inline int GetPos(int Value){
        return lower_bound(HashData.begin(),HashData.end(),Value)-HashData.begin();
    }
    
    struct SegmentTree{
        struct SegTreeNode{
            int Size;
            int Lson,Rson;
        };
        SegTreeNode SegTree[MAXN<<5];
        int ROOT[MAXN];
        int Index=0;
    
        void Output(int Root,int L,int R){
            if(L==R){cout<<SegTree[Root].Size<<" ";return;}
            int mid=(L+R)>>1;
            Output(SegTree[Root].Lson,L,mid);
            Output(SegTree[Root].Rson,mid+1,R);
            return;
        }
    
        inline void Push_Up(int Root){
            int ls=SegTree[Root].Lson;
            int rs=SegTree[Root].Rson;
            SegTree[Root].Size=SegTree[ls].Size+SegTree[rs].Size;
            return;
        }
    
        void Build_Empty_SegTree(int &Root,int L,int R){
            Root=++Index;
            if(L==R){SegTree[Root].Size=0;return;}
            int mid=(L+R)>>1;
            Build_Empty_SegTree(SegTree[Root].Lson,L,mid);
            Build_Empty_SegTree(SegTree[Root].Rson,mid+1,R);
            Push_Up(Root);
            return;
        }
    
        void Insert_Node(int &Pre,int &Cur,int L,int R,int Pos){
            Cur=++Index;
            SegTree[Cur]=SegTree[Pre];
            if(L==R){++SegTree[Cur].Size;return;}
            int mid=(L+R)>>1;
            if(Pos<=mid) Insert_Node(SegTree[Pre].Lson,SegTree[Cur].Lson,L,mid,Pos);
            else Insert_Node(SegTree[Pre].Rson,SegTree[Cur].Rson,mid+1,R,Pos);
            Push_Up(Cur);
            return;
        }
    
        int Get_Kth(int Pre,int Cur,int L,int R,int Kth){
            if(L==R) return L;
            int mid=(L+R)>>1;
            int CLson=SegTree[Cur].Lson;
            int PLson=SegTree[Pre].Lson;
            int Lsize=SegTree[CLson].Size-SegTree[PLson].Size;
            if(Kth<=Lsize) return Get_Kth(SegTree[Pre].Lson,SegTree[Cur].Lson,L,mid,Kth);
            return Get_Kth(SegTree[Pre].Rson,SegTree[Cur].Rson,mid+1,R,Kth-Lsize);
        }
    };
    SegmentTree Tree;
    
    int main(){
        Read(N);Read(M);
        HashData.resize(N+1);
        for(RG i=1;i<=N;++i){
            Read(Data[i]);
            HashData[i]=Data[i];
        }
        Discretization();
        Tree.Build_Empty_SegTree(Tree.ROOT[0],1,ElemNum);
        for(RG i=1;i<=N;++i){
            int Pos=GetPos(Data[i]);
            Tree.Insert_Node(Tree.ROOT[i-1],Tree.ROOT[i],1,ElemNum,Pos);
        }
        while(M--){
            int L,R,Kth,Pos;
            Read(L);Read(R);Read(Kth);
            Pos=Tree.Get_Kth(Tree.ROOT[L-1],Tree.ROOT[R],1,ElemNum,Kth);
            printf("%d
    ",HashData[Pos]);
        }
        return 0;
    }
    
  • 相关阅读:
    Linux makefile 教程 很具体,且易懂
    Java串口通信具体解释
    今年股票注定有一波行情(重申6月10号的观点)
    hotmail邮箱pop3server设置方法
    html的下拉框的几个基本使用方法
    第1次实验——NPC问题(回溯算法、聚类分析)
    【甘道夫】Hive 0.13.1 on Hadoop2.2.0 + Oracle10g部署详细解释
    C该程序生成一个唯一的序列号
    高速分拣(1)的基本算法
    Eclipse项目崩溃,使用MyEclipse解决
  • 原文地址:https://www.cnblogs.com/AEMShana/p/12663688.html
Copyright © 2011-2022 走看看