模板题:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+10; const int mod=1e9+7; struct node{ int l,r,key,mi,rnd,rev,add,size; }tr[N]; int n,x,y,z,root,idx; int get(int x){ tr[++idx]={0,0,x,x,rand(),0,0,1}; return idx; } void pushdown(int u){ if(tr[u].rev){ tr[tr[u].l].rev ^= 1, tr[tr[u].r].rev ^= 1; swap(tr[u].l, tr[u].r); tr[u].rev = 0; } if(tr[u].add){ int x=tr[u].add; if(tr[u].l) tr[tr[u].l].key+=x,tr[tr[u].l].add+=x,tr[tr[u].l].mi+=x; if(tr[u].r) tr[tr[u].r].key+=x,tr[tr[u].r].add+=x,tr[tr[u].r].mi+=x; tr[u].add=0; } } void pushup(int p){ tr[p].mi = min(tr[p].key, min(tr[tr[p].l].mi, tr[tr[p].r].mi)); tr[p].size = tr[tr[p].l].size + tr[tr[p].r].size + 1; } void split(int p,int siz,int &x,int &y){ if(!p) x=y=0; else{ pushdown(p); if(tr[tr[p].l].size<siz){ x=p; split(tr[p].r,siz-tr[tr[p].l].size-1,tr[p].r,y); } else{ y=p; split(tr[p].l,siz,x,tr[p].l); } pushup(p); } } //保证输入的值按序列号左大右小 int merge(int x,int y){ if(!x||!y) return x+y; if(tr[x].rnd>tr[y].rnd){ pushdown(x); tr[x].r=merge(tr[x].r,y); pushup(x); return x; } else{ pushdown(y); tr[y].l=merge(x,tr[y].l); pushup(y); return y; } } int main(){ cin>>n; tr[0].mi=2e9; int i; for(i=1;i<=n;i++){ int x; scanf("%d",&x); root=merge(root,get(x)); } string s; int m; cin>>m; while(m--){ cin>>s; if(s=="ADD"){ int l,r,d; scanf("%d%d%d",&l,&r,&d); split(root,l-1,x,y);split(y,r-l+1,y,z); tr[y].add+=d,tr[y].key+=d; y=merge(y,z); root=merge(x,y); } else if(s=="REVERSE"){ int l,r; scanf("%d%d",&l,&r); split(root,l-1,x,y);split(y,r-l+1,y,z); tr[y].rev^=1; y=merge(y,z); root=merge(x,y); } else if(s=="REVOLVE"){ int l,r,t,tmp1,tmp2,tmp3,tmp4; scanf("%d%d%d",&l,&r,&t); t%=(r-l+1); if(t){ split(root,l-1,tmp1,tmp2); split(tmp2,r-l+1-t,tmp2,tmp3); split(tmp3,t,tmp3,tmp4); root=merge(merge(tmp1,tmp3),merge(tmp2,tmp4)); } } else if(s[0]=='I'){ int l,p; scanf("%d%d",&l,&p); split(root,l,x,y); root=merge(x,merge(get(p),y)); } else if(s[0] == 'D') { int d; scanf("%d", &d); split(root, d - 1,x, y), split(y, 1, y, z); root = merge(x,z); } else if(s[0] == 'M') { int l,r;scanf("%d%d", &l, &r); split(root, l - 1, x, y), split(y, r - l + 1, y,z); printf("%d\n", tr[y].mi); root = merge(x, merge(y, z)); } } }