zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Linux常见问题解决
    使用npm国内镜像
    常用CSS备忘
    如何把JavaScript数组中指定的一个元素移动到第一位
    教你如何将word中的表格完美粘贴到ppt中
    测试开发之路--一个小小工程师的回首
    一篇文章读完50篇摄影教程(托马斯的2016总结)
    李开复推荐的30本创业/管理/互联网必须看的电子书
    摩拜单车深度产品体验报告
    Word2016(2013)怎么从任意页插入起始页码
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11427320.html
Copyright © 2011-2022 走看看