RMQ with shifts

In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for each query (LR)(L$ \le$R), 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(i1i2i3,..., ik)(i1 < i2 < ... < ikk > 1)

 

we do a left ``circular shift" of A[i1]A[i2], ..., A[ik].

For example, if A={6, 2, 4, 85, 1, 4}, then shift(2, 4, 5, 7) yields {68, 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 nq ( 1$ \le$n$ \le$100, 0001$ \le$q$ \le$250, 000), the number of integers in array A, and the number of operations. The next line contains n positive integers not greater than 100,000, the initial elements in array A. Each of the next q lines contains an operation. Each operation is formatted as a string having no more than 30 characters, with no space characters inside. All operations are guaranteed to be valid.

 


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

 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 }
View Code

 

posted @ 2013-07-20 22:36  1002liu  阅读(292)  评论(0编辑  收藏  举报