splay
struct splay_tree{ static const int maxn=2e6+10; int ch[maxn][2],fa[maxn]; int miv[maxn],val[maxn],add[maxn],rev[maxn],siz[maxn]; int rub[maxn],rub_;//回收池 int rt,tot; //数据结束 void pushup(int h){//维持,回溯 int l=ch[h][0],r=ch[h][1]; miv[h]=val[h]; if(l)miv[h]=min(miv[h],miv[l]); if(r)miv[h]=min(miv[h],miv[r]); siz[h]=siz[l]+siz[r]+1; } void pushdown(int h){//下放懒惰标记 int l=ch[h][0],r=ch[h][1]; if(add[h]){ add[l]+=add[h];val[l]+=add[h];miv[l]+=add[h]; add[r]+=add[h];val[r]+=add[h];miv[r]+=add[h]; add[h]=0; } if(rev[h]){ rev[l]^=1;rev[r]^=1;rev[h]^=1; swap(ch[h][0],ch[h][1]); } } void rotate(int h){//旋转 int f=fa[h],g=fa[f]; if(g){ int c=(f==ch[g][1]); ch[g][c]=h; } fa[f]=h;fa[h]=g; int c=(h==ch[f][1]); fa[ch[h][!c]]=f; ch[f][c]=ch[h][!c]; ch[h][!c]=f; if(f==rt) rt=h; pushup(f); pushup(h); } void splay(int h,int aim){//伸展 static int sta[maxn]; int top=1;sta[top]=h; for(int i=h;fa[i]!=0;i=fa[i])sta[++top]=fa[i]; for(int i=top;i>=1;--i)pushdown(sta[i]); while(fa[h]^aim){ int f=fa[h],g=fa[f]; if(g^aim)rotate(f); rotate(h); } pushup(h); } void newnode(int&h,int f,int val_){ if(rub_!=-1)h=rub[rub_--];//如果rub是空的,我们就从rub里面找 else h=++tot;//否则使用新的 ch[h][0]=ch[h][1]=0; fa[h]=f; miv[h]=val[h]=val_; add[h]=rev[h]=0; siz[h]=1; } void built(int&x,char*data,int l,int r,int f){ if(l>r)return; int mid=(l+r)>>1; newnode(x,f,data[mid]); built(ch[x][0],data,l,mid-1,x); built(ch[x][1],data,mid+1,r,x); pushup(x); } void ini(){//建只含有两个节点的空树 rub_=-1;tot=0; newnode(rt,0,0); newnode(ch[rt][1],rt,0); pushup(ch[rt][1]); pushup(rt); } void insert(int a,char*data,int l,int r){//把data添加在a的后面, int x=id(a),y=id(a+1); splay(x,0); splay(y,x); built(ch[y][0],data,l,r,y); pushup(y); pushup(x); } int id(int k){//返回第k个数,下标是从1开始的 int h; pushdown(rt); for(h=rt;siz[ch[h][0]]+1!=k;){ if(siz[ch[h][0]]+1>k)h=ch[h][0]; else{ k-=(siz[ch[h][0]]+1); h=ch[h][1]; } pushdown(h); } return h; } //以上函数必备,尽量不要修改 //////////////////////// void rubbish(int&rt){ if(ch[rt][0])rubbish(ch[rt][0]); if(ch[rt][1])rubbish(ch[rt][1]); rub[++rub_]=rt; rt=0; } void erase(int a,int b){ int x=id(a-1), y=id(b+1); splay(x,0); splay(y,x); rubbish(ch[y][0]); pushup(y); pushup(x); } int getmin(int a,int b){ int x=id(a-1), y=id(b+1); splay(x,0); splay(y,x); return miv[ch[y][0]]; } void addval(int a,int b,int d){ int x=id(a-1), y=id(b+1); splay(x,0); splay(y,x); int w=ch[y][0]; add[w]+=d; val[w]+=d; miv[w]+=d; pushup(y); pushup(x); } void reserve(int a,int b){ int x=id(a-1), y=id(b+1); splay(x,0); splay(y,x); rev[ch[y][0]]^=1; } }tree;
本博客所有文章除特別声明外,均采用
CC BY 4.0
许可协议。转载请注明来源
fightinggg
!