• P3835 【模板】可持久化平衡树


    题面

    https://www.luogu.org/problem/P3835

    题解

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<ctime>
    
    using namespace std;
    struct fhq_treap {
      int v[500050*50],fix[500050*50],ch[500050*50][2],siz[500050*50];
      int root[500050],cnt;
      void clear() {cnt=0;}
      void copy(int x,int y) {
        v[y]=v[x]; fix[y]=fix[x]; ch[y][0]=ch[x][0]; ch[y][1]=ch[x][1]; siz[y]=siz[x];
      }
      void update(int x) { siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1; }
      void split(int k,int x,int y,int &ch1,int &ch2) {
        if (!x) {
          ch2=ch1=0;
          return;
        }
        copy(x,y);
        if (v[y]<=k) {
          ch1=y;
          split(k,ch[y][1],++cnt,ch[y][1],ch2);
        }
        else {
          ch2=y;
          split(k,ch[y][0],++cnt,ch1,ch[y][0]);
        }
        update(y);
      }
      int merge(int x,int y) {
        if (!x || !y) return x+y;
        if (fix[x]<fix[y]) {
          ch[x][1]=merge(ch[x][1],y);
          update(x);
          return x;
        }
        else {
          ch[y][0]=merge(x,ch[y][0]);
          update(y);
          return y;
        }
      }
      int newnode(int val) {
        ++cnt;
        v[cnt]=val; fix[cnt]=rand(); siz[cnt]=1;
        return cnt;
      }
      void insert(int his,int cur,int val) {
        int root1=0,root2=0;
        split(val,root[his],++cnt,root1,root2);
        root[cur]=merge(merge(root1,newnode(val)),root2);
      }
      void erase(int his,int cur,int val) {
        int root1=0,root2=0,root3=0;
        split(val,root[his],++cnt,root1,root3);
        split(val-1,root1,++cnt,root1,root2);
        root2=merge(ch[root2][0],ch[root2][1]);
        root[cur]=merge(merge(root1,root2),root3);
      }
      int findkth(int k,int his,int cur) {
        int now=root[cur]=root[his];
        int rk=1;
        while (now) {
          if (siz[ch[now][0]]+rk==k) return v[now];
          else if (siz[ch[now][0]]+rk>k) now=ch[now][0]; else rk+=siz[ch[now][0]]+1,now=ch[now][1];
        }
        return -1;
      }
      int findrank(int k,int his,int cur) {
        int root1=0,root2=0;
        split(k-1,root[his],++cnt,root1,root2);
        int ret=siz[root1]+1;
        root[cur]=merge(root1,root2);
        return ret;
      }
      int findpre(int k,int his,int cur) {
        int pre=-2147483647;
        int now=root[cur]=root[his];
        while (now) {
          if (v[now]<k) pre=max(pre,v[now]),now=ch[now][1]; else now=ch[now][0];
        }
        return pre;
      }
      int findsuc(int k,int his,int cur) {
        int suc=2147483647;
        int now=root[cur]=root[his];
        while (now) {
          if (v[now]>k) suc=min(suc,v[now]),now=ch[now][0]; else now=ch[now][1];
        }
        return suc;
      }
    } treap;
    
    int n;
    int main() {
      int i,his,opt,x;
      srand(time(0));
      treap.clear();
      scanf("%d",&n);
      for (i=1;i<=n;i++) {
        scanf("%d %d %d",&his,&opt,&x);
        if (opt==1) treap.insert(his,i,x);
        if (opt==2) treap.erase(his,i,x);
        if (opt==3) printf("%d
    ",treap.findrank(x,his,i));
        if (opt==4) printf("%d
    ",treap.findkth(x,his,i));
        if (opt==5) printf("%d
    ",treap.findpre(x,his,i));
        if (opt==6) printf("%d
    ",treap.findsuc(x,his,i));
      }
      return 0;
    }
  • 相关阅读:
    Machine Learning、Date Mining、IR&NLP 会议期刊论文推荐
    Natural Language Processing, 2017, Mar.29, Weekly Report
    【Turing Award】Robin Milner And Butler W. Lampson
    【word2vec】Distributed Representation——词向量
    【Java】HashTable和HashMap区别
    String, StringBuffer,StringBuilder的区别
    【Java】自动类型转换规则
    【Miktex】使用教程以及数学符号整理总结
    【JDK】各个版本垃圾收集器
    【Java】异常类处理层次
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11427320.html
Copyright © 2020-2023  润新知