RMQ with shifts
In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for each query (L, R)(LR), we report the minimum value among A[L], A[L + 1], ..., A[R]. Note that the indices start from 1, i.e. the left-most element is A[1].
In this problem, the array A is no longer static: we need to support another operation
shift(i1, i2, i3,..., ik)(i1 < i2 < ... < ik, k > 1)
we do a left ``circular shift" of A[i1], A[i2], ..., A[ik].
For example, if A={6, 2, 4, 8, 5, 1, 4}, then shift(2, 4, 5, 7) yields {6, 8, 4, 5, 4, 1, 2}. After that,shift(1, 2) yields 8, 6, 4, 5, 4, 1, 2.
Input
There will be only one test case, beginning with two integers n, q ( 1![$ \le$](http://uva.onlinejudge.org/external/122/12299img1.png)
![$ \le$](http://uva.onlinejudge.org/external/122/12299img1.png)
![$ \le$](http://uva.onlinejudge.org/external/122/12299img1.png)
![$ \le$](http://uva.onlinejudge.org/external/122/12299img1.png)
Warning: The dataset is large, better to use faster I/O methods.
Output
For each query, print the minimum value (rather than index) in the requested range.
Sample Input
7 5 6 2 4 8 5 1 4 query(3,7) shift(2,4,5,7) query(1,4) shift(1,2) query(2,2)
Sample Output
1 4 6
The Seventh Hunan Collegiate Programming Contest
Problemsetter: Rujia Liu, Special Thanks: Yiming Li & Jane Alam Jan
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<algorithm> 3 #define N 122222 4 using namespace std; 5 const int inf=1e9; 6 7 int num[N]; 8 struct Tree 9 { 10 int l,r; 11 int mmin; 12 } tree[N*4]; 13 void push_up(int root) 14 { 15 tree[root].mmin=min(tree[root<<1].mmin,tree[root<<1|1].mmin); 16 } 17 18 void build(int root,int l,int r) 19 { 20 tree[root].l=l; 21 tree[root].r=r; 22 if(tree[root].l==tree[root].r) 23 { 24 tree[root].mmin=num[l]; 25 return; 26 } 27 int mid=(l+r)/2; 28 build(root<<1,l,mid); 29 build(root<<1|1,mid+1,r); 30 push_up(root); 31 } 32 void update(int root,int pos,int val) 33 { 34 if(tree[root].l==tree[root].r) 35 { 36 tree[root].mmin=val; 37 return; 38 } 39 int mid=(tree[root].l+tree[root].r)/2; 40 if(pos<=mid) update(root<<1,pos,val); 41 else update(root<<1|1,pos,val); 42 push_up(root); 43 } 44 int query(int root,int L,int R) 45 { 46 if(L<=tree[root].l&&R>=tree[root].r) return tree[root].mmin; 47 int mid=(tree[root].l+tree[root].r)/2,ret=inf; 48 if(L<=mid) ret=min(ret,query(root<<1,L,R)); 49 if(R>mid) ret=min(ret,query(root<<1|1,L,R)); 50 return ret; 51 } 52 53 int main() 54 { 55 int n,q,x,y; 56 int stk[1111]; 57 int cnt; 58 char s[11]; 59 scanf("%d%d",&n,&q); 60 for (int i=1; i<=n; i++) scanf("%d",&num[i]); 61 build(1,1,n); 62 while (q--) 63 { 64 scanf("%6s",s); 65 if (s[0]=='q') 66 { 67 scanf("%d,%d)",&x,&y); 68 printf("%d\n",query(1,x,y)); 69 } 70 if (s[0]=='s') 71 { 72 char c; 73 int rm; 74 cnt=0; 75 while (scanf("%d%c",&x,&c)) 76 { 77 stk[cnt++]=x; 78 if (cnt==1) rm=num[stk[0]]; 79 else 80 { 81 num[stk[cnt-2]]=num[stk[cnt-1]]; 82 update(1,stk[cnt-2],num[stk[cnt-2]]); 83 } 84 if (c==')') break; 85 } 86 num[stk[cnt-1]]=rm; 87 update(1,stk[cnt-1],num[stk[cnt-1]]); 88 } 89 } 90 91 return 0; 92 }