http://www.lydsy.com/JudgeOnline/problem.php?id=1895
用来练习fhq_treap的题。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<bits/stdc++.h> const int maxn=100015; using namespace std; int n,m,a[maxn]; struct Ttreap{ int tot; static const int maxnode=2000015; struct Tnode{ Tnode *c[2];bool rev; int key,siz,add,val,fmn; void update(){ siz=c[0]->siz+c[1]->siz+1; fmn=min(c[0]->fmn,c[1]->fmn);fmn=min(fmn,val); } void add_rev(){if (siz){rev^=1;swap(c[0],c[1]);}} void add_add(int v){if (siz){add+=v;val+=v;fmn+=v;}} void clear(){ if (!siz) return; if (rev){c[0]->add_rev();c[1]->add_rev();rev=0;} if (add){c[0]->add_add(add);c[1]->add_add(add);add=0;} } }T[maxnode],*null,*root; void clear(){ tot=0;null=T; null->c[0]=null->c[1]=null; null->siz=null->add=null->rev=0; null->fmn=null->val=2147483647; } Tnode *newnode(int v){ Tnode *cur=T+(++tot); cur->c[0]=cur->c[1]=null; cur->siz=1;cur->add=cur->rev=0; cur->val=cur->fmn=v;cur->key=rand(); return cur; } void build(){ static Tnode *stk[maxn];int top=0; for (int i=1;i<=n;++i){ Tnode *cur=newnode(a[i]),*last=null; while (top&&stk[top]->key>cur->key){stk[top]->update();last=stk[top--];} cur->c[0]=last;cur->update();if (top) stk[top]->c[1]=cur; stk[++top]=cur; } while (top) stk[top--]->update(); root=stk[1]; } Tnode *merge(Tnode *x,Tnode *y){ if (x==null) return y; if (y==null) return x; x->clear();y->clear(); if (x->key<y->key){x->c[1]=merge(x->c[1],y);x->update();return x;} else{y->c[0]=merge(x,y->c[0]);y->update();return y;} } pair<Tnode*,Tnode*> split(Tnode *x,int rank){ if (!rank) return make_pair(null,x); x->clear();pair<Tnode*,Tnode*> y; if (rank<=x->c[0]->siz){ y=split(x->c[0],rank); x->c[0]=y.second;x->update();y.second=x; } else{ y=split(x->c[1],rank-x->c[0]->siz-1); x->c[1]=y.first;x->update();y.first=x; } return y; } void add(int l,int r,int v){ pair<Tnode*,Tnode*> y=split(root,l-1); pair<Tnode*,Tnode*> z=split(y.second,r-l+1); z.first->add_add(v); root=merge(y.first,z.first);root=merge(root,z.second); } int query(int l,int r){ pair<Tnode*,Tnode*> y=split(root,l-1); pair<Tnode*,Tnode*> z=split(y.second,r-l+1); int res=z.first->fmn; root=merge(y.first,z.first);root=merge(root,z.second); return res; } void insert(int pos,int v){ pair<Tnode*,Tnode*> y=split(root,pos); Tnode *cur=newnode(v); root=merge(y.first,cur);root=merge(root,y.second); } void remove(int pos){ pair<Tnode*,Tnode*> y=split(root,pos-1); pair<Tnode*,Tnode*> z=split(y.second,1); root=merge(y.first,z.second); } void reverse(int l,int r){ pair<Tnode*,Tnode*> y=split(root,l-1); pair<Tnode*,Tnode*> z=split(y.second,r-l+1); z.first->add_rev(); root=merge(y.first,z.first);root=merge(root,z.second); } void revolve(int l,int r,int t){ t%=(r-l+1);if (!t) return; pair<Tnode*,Tnode*> y=split(root,l-1); pair<Tnode*,Tnode*> z=split(y.second,r-l+1); pair<Tnode*,Tnode*> w=split(z.first,r-l+1-t); root=merge(w.second,w.first);root=merge(y.first,root);root=merge(root,z.second); } }treap; void init(){ scanf("%d",&n);srand(19990917); for (int i=1;i<=n;++i) scanf("%d",&a[i]); scanf("%d",&m);treap.clear();treap.build(); } void add(){ int x,y,v;scanf("%d%d%d",&x,&y,&v); treap.add(x,y,v); } void query(){ int x,y;scanf("%d%d",&x,&y); printf("%d\n",treap.query(x,y)); } void insert(){ int x,v;scanf("%d%d",&x,&v); treap.insert(x,v); } void remove(){ int x;scanf("%d",&x); treap.remove(x); } void reverse(){ int x,y;scanf("%d%d",&x,&y); treap.reverse(x,y); } void revolve(){ int x,y,t;scanf("%d%d%d",&x,&y,&t); treap.revolve(x,y,t); } void work(){ for (int i=1;i<=m;++i){ char op[10];scanf("%s",op); switch (op[0]){ case 'A':add();break; case 'M':query();break; case 'I':insert();break; case 'D':remove();break; case 'R':op[3]=='E'?reverse():revolve();break; } } } int main(){ init(); work(); return 0; }