P5055 [template] can persist literary balanced tree

Face questions

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

answer

#include<cstdio>
#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;

const long long size=250000*50;

struct fhq_treap {
  long long v[size],ch[size][2],fix[size],siz[size],sum[size]; 
  bool rev[size];
  long long root[200050];
  long long cnt;
  void clear() {cnt=0; v[0]=ch[0][1]=ch[0][0]=fix[0]=siz[0]=sum[0]=rev[0]=0; root[0]=0;}
  void pushr(long long x) {
    if (!rev[x]) return;
    rev[x]=false;
    swap(ch[x][0],ch[x][1]);
    if (ch[x][0]) {
      copy(ch[x][0],++cnt);
      ch[x][0]=CNT; 
      rev [CNT] ^ = 1 ; 
    } 
    If (ch [x] [ 1 ]) { 
      copy (ch [x] [ 1 ] ++ CNT); 
      ch [x] [ 1 ] = CNT; 
      rev [CNT] ^ = 1 ; 
    } 
  } 
  Void update ( long  long x) { 
    siz [x] = 1 + siz [ch [x] [ 0 ]] + siz [ch [x] [ 1 ]]; 
    sum [x] = v [x] + sum [ch [x] [ 0 ]] + sum [ch [x] [ 1 ]]; 
  } 
  Void copy (long long x,long long y) {
    siz[y]=siz[x]; ch[y][0]=ch[x][0]; ch[y][1]=ch[x][1];
    fix[y]=fix[x]; v[y]=v[x]; rev[y]=rev[x]; sum[y]=sum[x];
  }
  // 1-k  k+1-n
  void split(long long k,long long x,long long y,long long &ch1,long long &ch2) {
    if (x==0) {
      ch1=ch2=0;
      return;
    }
    copy(x,y);
    pushr(y); 
    if (siz[ch[y][0]]+1<=k) {
      ch1=y;
      split(k-siz[ch[y][0]]-1,ch[y][1],++cnt,ch[y][1],ch2);
      //update(ch1);
    }
    else {
      ch2=y;
      split(k,ch[y][0],++cnt,ch1,ch[y][0]);
      //update(ch2);
    }
    update(y);
  }
  long long merge(long long x,long long y) {
    if (!x || !y) return x+y;
    pushr(x); pushr(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;
    }
  }
  long long newnode(long long val) {
    ++cnt;
    sum[cnt]=v[cnt]=val; siz[cnt]=1; fix[cnt]=rand();
    ch[cnt][0]=ch[cnt][1]=0; rev[cnt]=0;
    return cnt;
  }
  void insert(long long his,long long cur,long long p,long long val) {
    long long root1=0,root2=0;
    split(p,root[his],++cnt,root1,root2);
    root[cur]=merge(merge(root1,newnode(val)),root2);
  }
  void erase(long long his,long long cur,long long p) {
    long long root1=0,root2=0,root3=0;
    split(p-1,root[his],++cnt,root1,root3);
    split(1,root3,++cnt,root2,root3);
    root[cur]=merge(root1,root3);
  }
  long long query(long long his,long long cur,long long l,long long r) {
    long long root1=0,root2=0,root3=0;
    split(r,root[his],++cnt,root2,root3);
    split(l-1,root2,++cnt,root1,root2);
    //cout<<root2<<endl;
    long long ret=sum[root2];
    root[cur]=merge(merge(root1,root2),root3);
    return ret;
  }
  void rever(long long his,long long cur,long long l,long long r) {
    long long root1=0,root2=0,root3=0;
    //split(l-1,root[his],++cnt,root1,root2);
    //split(r-l+1,root2,++cnt,root2,root3);
    split(r,root[his],++cnt,root2,root3);
    split(l-1,root2,++cnt,root1,root2);
    rev[root2]^=1;
    root[cur]=merge(merge(root1,root2),root3);
  }
} treap;

long long n;
int main() {
  long long i,opt,his,p,x,lastans=0,l,r;
  srand(time(0));
  treap.clear();
  scanf("%lld",&n);
  for (i=1;i<=n;i++) {
    scanf("%lld %lld",&his,&opt);
    if (opt==1) {
      scanf("%lld %lld",&p,&x);
      p^=lastans; x^=lastans;
      treap.insert(his,i,p,x);
    }
    if (opt==2) {
      scanf("%lld",&p);
      p^=lastans;
      treap.erase(his,i,p);
    }
    if (opt==3) {
      scanf("%lld %lld",&l,&r);
      l^=lastans; r^=lastans;
      treap.rever(his,i,l,r);
    }
    if (opt==4) {
      scanf("%lld %lld",&l,&r);
      l^=lastans; r^=lastans;
      //cout<<l<<" "<<r<<endl;
      lastans=treap.query(his,i,l,r);
      printf("%lld\n",lastans);
    }
  }
  return 0;
}

 

Guess you like

Origin www.cnblogs.com/shxnb666/p/11427317.html