3: Lydsy1895 SuperMemo
Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 15 Solved: 11
[Submit][Status][Web Board]
Description
给出一个初始序列fA1;A2;:::Ang,要求你编写程序支持如下操作:
1. ADDxyD:给子序列fAx:::Ayg的每个元素都加上D。例如对f1,2, 3,4,5g执行"ADD 241" 会得到f1,3,4,5,5g。
2. REVERSExy:将子序列fAx:::Ayg翻转。例如对f1,2,3,4,5g执行"REVERSE 24"会得到f1,4,3,2,5g。
3. REVOLVExyT:将子序列fAx:::Ayg旋转T个单位。例如,对f1,2,3,4,5g执行"REVOLVE 242"会得到f1,3,4,2,5g。
4. INSERTxP:在Ax后插入P。例如,对f1,2,3,4,5g执行"INSERT 24"会得到f1,2,4,3,4,5g。
5. DELETEx:删去Ax。例如,对f1,2,3,4,5g执行"DELETE 2"会得到f1,3,4,5g。
6. MINxy:查询子序列fAx:::Ayg中的最小元素。例如,对于序列f1, 2,3,4,5g,询问"MIN 24"的返回应为2。
1. ADDxyD:给子序列fAx:::Ayg的每个元素都加上D。例如对f1,2, 3,4,5g执行"ADD 241" 会得到f1,3,4,5,5g。
2. REVERSExy:将子序列fAx:::Ayg翻转。例如对f1,2,3,4,5g执行"REVERSE 24"会得到f1,4,3,2,5g。
3. REVOLVExyT:将子序列fAx:::Ayg旋转T个单位。例如,对f1,2,3,4,5g执行"REVOLVE 242"会得到f1,3,4,2,5g。
4. INSERTxP:在Ax后插入P。例如,对f1,2,3,4,5g执行"INSERT 24"会得到f1,2,4,3,4,5g。
5. DELETEx:删去Ax。例如,对f1,2,3,4,5g执行"DELETE 2"会得到f1,3,4,5g。
6. MINxy:查询子序列fAx:::Ayg中的最小元素。例如,对于序列f1, 2,3,4,5g,询问"MIN 24"的返回应为2。
Input
第一行包含一个整数n,表示初始序列的长度。
以下n行每行包含一个整数,描述初始的序列。
接下来一行包含一个整数m,表示操作的数目。以下m行每行描述一个操作。n,m<=10^6
以下n行每行包含一个整数,描述初始的序列。
接下来一行包含一个整数m,表示操作的数目。以下m行每行描述一个操作。n,m<=10^6
Output
对于所有"MIN"操作,输出正确的答案,每行一个。
Sample Input
5
1
2
3
4
5
2
ADD 2 4 1
MIN 4 5
Sample Output
5
HINT
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define inf 2100000000 const int maxn=300000+10; int a[maxn],f[maxn],ch[maxn][2],key[maxn],Min[maxn],Size[maxn],ver[maxn],add[maxn],root; int sz; void Clear(int x){ f[x]=ch[x][0]=ch[x][1]=key[x]=Size[x]=Min[x]=ver[x]=add[x]=0; } int getself(int x){ return ch[f[x]][1]==x; } void update(int x){ Size[x]=Size[ch[x][0]]+Size[ch[x][1]]+1; Min[x]=key[x]; if(ch[x][0]) Min[x]=min(Min[x],Min[ch[x][0]]); if(ch[x][1]) Min[x]=min(Min[x],Min[ch[x][1]]); } void pushdown(int x){ if(x){ if(ver[x]){ ver[ch[x][0]]^=1; ver[ch[x][1]]^=1; swap(ch[x][0],ch[x][1]); ver[x]=0; } if(add[x]){ add[ch[x][0]]+=add[x],add[ch[x][1]]+=add[x]; Min[ch[x][0]]+=add[x],Min[ch[x][1]]+=add[x]; key[ch[x][0]]+=add[x],key[ch[x][1]]+=add[x]; add[x]=0; } } } int build(int l,int r,int fa){ if(l>r) return 0; int mid=(l+r)>>1,now=++sz; f[sz]=fa,key[sz]=a[mid]; int tl=build(l,mid-1,now); int tr=build(mid+1,r,now); ch[now][0]=tl; ch[now][1]=tr; update(now); return now; } int Find(int x){ int now=root; while(1){ pushdown(now); if(x<=Size[ch[now][0]]) now=ch[now][0]; else { x-=Size[ch[now][0]]; if(x==1) return now; now=ch[now][1]; --x; } } } void Rotate(int x){ pushdown(f[x]); pushdown(x); int old=f[x],oldf=f[old],which=getself(x); ch[old][which]=ch[x][which^1],f[ch[old][which]]=old; ch[x][which^1]=old;f[old]=x; f[x]=oldf; if(oldf){ ch[oldf][ch[oldf][1]==old]=x; } update(old); update(x); } void splay(int x,int tar){ for (int fa;(fa=f[x])!=tar;Rotate(x)) if(f[fa]!=tar) Rotate( (getself(x)==getself(fa))?fa:x); if(!tar) root=x; } int main(){ char s[20]; int n,m; scanf("%d",&n); a[1]=-inf; a[n+2]=inf; int x,y,d; for (int i=1;i<=n;i++) scanf("%d",&a[i+1]); root=build(1,n+2,0); scanf("%d",&m); for (int i=1;i<=m;i++){ scanf("%s",s); switch(s[0]){ case 'A': { scanf("%d%d%d",&x,&y,&d); if(x>y) swap(x,y); int aa=Find(x); int bb=Find(y+2); splay(aa,0); splay(bb,aa); Min[ch[ch[root][1]][0]]+=d; key[ch[ch[root][1]][0]]+=d; add[ch[ch[root][1]][0]]+=d; update(ch[root][1]); update(root); break; } case 'R': { if(s[3]=='E'){ scanf("%d%d",&x,&y); if(x==y) continue; if(x>y) swap(x,y); int aa=Find(x); int bb=Find(y+2); splay(aa,0); splay(bb,aa); ver[ch[ch[root][1]][0]]^=1; } else { scanf("%d%d%d",&x,&y,&d); if(x>y) swap(x,y); d%=y-x+1; if(!d) continue; int aa=Find(y-d+1); int bb=Find(y+2); splay(aa,0); splay(bb,aa); int now=ch[ch[root][1]][0]; ch[ch[root][1]][0]=0; update(ch[root][1]); update(root); aa=Find(x); bb=Find(x+1); splay(aa,0); splay(bb,aa); ch[ch[root][1]][0]=now; f[now]=ch[root][1]; update(ch[root][1]); update(root); } break; } case 'I': { scanf("%d%d",&x,&d); int aa=Find(x+1); int bb=Find(x+2); splay(aa,0); splay(bb,aa); ch[ch[root][1]][0]=++sz; f[sz]=ch[root][1]; Size[sz]=1; key[sz]=d; Min[sz]=d; update(ch[root][1]); update(root); break; } case 'D': { scanf("%d",&x); int aa=Find(x); int bb=Find(x+2); splay(aa,0); splay(bb,aa); int del=ch[ch[root][1]][0]; Clear(del); ch[ch[root][1]][0]=0; update(ch[root][1]); update(root); break ; } case 'M': { scanf("%d%d",&x,&y); if(x>y) swap(x,y); int aa=Find(x); int bb=Find(y+2); splay(aa,0); splay(bb,aa); int ans=Min[ch[ch[root][1]][0]]; printf("%d ",ans); break; } } } return 0; }