zoukankan      html  css  js  c++  java
  • 3065: 带插入区间K小值 树套树 + 替罪羊树 + 权值线段树

    经过周六一天,周一3个小时的晚自习,周二2个小时的疯狂debug,终于凭借自己切掉了这道树套树题.

    Code:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <queue>
    // 带插入区间 k 小值
    // 外层:替罪羊
    // 内层:权值线段树
    using namespace std;
    #define setIO(s) freopen(s".in","r",stdin), freopen(s".out","w",stdout) 
    #define debug()  printf("OK
    ") 
    #define maxn 11005000
    #define N 70002
    int n,lastans;
    struct Segment_Tree{
        struct Node{
            int ls,rs,siz; 
            Node(int ls=0,int rs=0,int siz=0):ls(ls),rs(rs),siz(siz){}
        }node[maxn];
        queue<int>Q; 
        void init(){ for(int i=1;i<maxn;++i) Q.push(i); }
        void newnode(int &o) { o=Q.front(), Q.pop(); }
        void update(int l,int r,int &o,int pos,int delta){
            if(!o) newnode(o); 
            node[o].siz+=delta;
            if(!node[o].siz) { dfs(o); return; }
            if(l==r) return;
            int mid=(l+r)>>1;
            if(pos<=mid) update(l,mid,node[o].ls,pos,delta);
            else update(mid+1,r,node[o].rs,pos,delta);
        }
        void dfs(int &o){
            if(!o)return;
            dfs(node[o].ls),Q.push(o),dfs(node[o].rs);
            node[o].siz=0;
            o=0; 
        }
    }segin;
    struct Binary_Search_Tree{
        inline bool check(int son,int o){
            if(son*10>=o*9) return true; 
            return false; 
        }
        int cnt,root;
        int seq[N],count[3]; 
        vector<int>re;
        struct Node{
            int ls,rs,siz,root,cur,val; 
            Node(int ls=0,int rs=0,int siz=0,int root=0,int cur=0,int val=0):ls(ls),rs(rs),root(root),cur(cur),val(val){}
        }node[maxn];
        inline void newnode(int &o,int val){  o=++cnt,node[o].val=val,node[o].siz=1;  }
        void dfs(int &o){
            if(!o) return;
            segin.dfs(node[o].root),segin.dfs(node[o].cur); 
            dfs(node[o].ls),re.push_back(o),dfs(node[o].rs);
            node[o].siz=0;
            o=0;
    
        }
        void construct(int l,int r,int &o){
            if(l>r)return;
            int mid=(l+r)>>1;
            o=re[mid];
     
            for(int i=l;i<=r;++i) 
                segin.update(0,N,node[o].root,node[re[i]].val,1);
     
            segin.update(0,N,node[o].cur,node[o].val,1);  
            if(l==r){ node[o].siz=1; return; } 
     
            construct(l,mid-1,node[o].ls), construct(mid+1,r,node[o].rs); 
            node[o].siz=node[node[o].ls].siz+node[node[o].rs].siz+1; 
        }
        inline void Rebuild(int &o){  re.clear(),dfs(o),construct(0,re.size()-1,o);   }
        void insert(int &o,int k,int val,bool is){
            if(!o){
                newnode(o,val),segin.update(0,N,node[o].root,val,1),segin.update(0,N,node[o].cur,val,1); 
                return;
            }
            ++node[o].siz, segin.update(0,N,node[o].root,val,1);
            bool tag; 
            if(k<=node[node[o].ls].siz+1) tag=check(node[node[o].ls].siz+1,node[o].siz), insert(node[o].ls,k,val,is||tag);
            else tag=check(node[node[o].rs].siz+1,node[o].siz), insert(node[o].rs,k-node[node[o].ls].siz-1,val,is||tag);
            if(!is&&tag)  Rebuild(o); 
        }
        int modify(int o,int pos,int delta){
            int num;
            if(pos==node[node[o].ls].siz+1) {
                segin.update(0,N,node[o].root,node[o].val,-1),segin.dfs(node[o].cur),node[o].cur=0; 
                segin.update(0,N,node[o].root,delta,1),segin.update(0,N,node[o].cur,delta,1);
                num=node[o].val,node[o].val=delta;
                return num;
            }
            if(pos<=node[node[o].ls].siz) num=modify(node[o].ls,pos,delta);
            else num=modify(node[o].rs,pos-node[node[o].ls].siz-1,delta);
            segin.update(0,N,node[o].root,num,-1),segin.update(0,N,node[o].root,delta,1); 
            return num; 
        }
        void Build(){
            scanf("%d",&n),re.clear();
            int tmp,x ;
            for(int i=1;i<=n;++i)
                scanf("%d",&tmp),newnode(x,tmp),re.push_back(x);
            construct(0,re.size()-1,root);  
        }
        void Get(int l,int r,int o,int L,int R){ 
            if(l>R||r<L||l>r||!o)return;
            if(l>=L&&r<=R) {  seq[++count[0]]=node[o].root; return;  } 
            int mid=node[node[o].ls].siz+l;                         
            if(mid>=L&&mid<=R&&mid<=r) seq[++count[0]]=node[o].cur;                          
            Get(l,mid-1,node[o].ls,L,R),Get(mid+1,r,node[o].rs,L,R); 
        }
        int solve(int l,int r,int k){
            if(l==r) return l;
            int lsum=0; 
            for(int i=1;i<=count[0];++i) {
                lsum+=segin.node[segin.node[seq[i]].ls].siz; 
            }
            int mid=(l+r)>>1;
            if(k>lsum) 
            {
                for(int i=1;i<=count[0];++i) seq[i]=segin.node[seq[i]].rs; 
                return solve(mid+1,r,k-lsum); 
            }
            else
            {
                for(int i=1;i<=count[0];++i)seq[i]=segin.node[seq[i]].ls; 
                return solve(l,mid,k); 
            }
        }
        void Insert(){
            int a,b;
            ++n,scanf("%d%d",&a,&b),a^=lastans,b^=lastans,insert(root,a,b,0); 
        }
        void Modify(){
            int a,b;
            scanf("%d%d",&a,&b),a^=lastans,b^=lastans,modify(root,a,b);
        } 
        int Query(){
            int L,R,k;
            count[0]=0, scanf("%d%d%d",&L,&R,&k),L^=lastans,R^=lastans,k^=lastans; 
            if(L>R)swap(L,R); 
            Get(1,n,root,L,R);
            return solve(0,N,k); 
        }
    }BST;
    int main(){
        //setIO("input");
        segin.init(), BST.Build(); 
        char opt[10];
        int q;
        scanf("%d",&q);
        while(q--){
            scanf("%s",opt); 
            if(opt[0]=='I') BST.Insert();
            if(opt[0]=='M') BST.Modify();  
            if(opt[0]=='Q') printf("%d
    ",lastans=BST.Query());
        } 
        return 0;
    } 
    

      

  • 相关阅读:
    oracle课堂笔记---第十九天
    oracle课堂笔记--第十八天
    oracle课堂随笔--第十七天
    oracle课堂随笔--第十六天
    oracle课堂随笔--第十五天
    oracle课堂随笔--第十四天
    oracle课堂笔记--第十三天
    oracle课堂随笔--第十一天
    Beta冲刺预备
    个人作业——软件产品分析
  • 原文地址:https://www.cnblogs.com/guangheli/p/10133888.html
Copyright © 2011-2022 走看看