C. RMQ with Shifts
Time Limit: 1000ms
Case Time Limit: 1000ms
Memory Limit: 131072KB
64-bit integer IO format: %lld Java class name: Main
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 ( 1n100, 000, 1q250, 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 解题:RMQ问题,更新比较有新意。。。。。。。。。。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <vector> 6 #include <climits> 7 #include <algorithm> 8 #include <cmath> 9 #define LL long long 10 using namespace std; 11 const int maxn = 100010; 12 struct node{ 13 int lt,rt,minVal; 14 }tree[maxn<<2]; 15 int d[maxn],u[30],cnt; 16 void build(int lt,int rt,int v){ 17 tree[v].lt = lt; 18 tree[v].rt = rt; 19 if(lt == rt){ 20 tree[v].minVal = d[lt]; 21 return; 22 } 23 int mid = (lt+rt)>>1; 24 build(lt,mid,v<<1); 25 build(mid+1,rt,v<<1|1); 26 tree[v].minVal = min(tree[v<<1].minVal,tree[v<<1|1].minVal); 27 } 28 int query(int lt,int rt,int v){ 29 if(tree[v].lt == lt && tree[v].rt == rt) return tree[v].minVal; 30 int mid = (tree[v].lt+tree[v].rt)>>1; 31 if(rt <= mid) return query(lt,rt,v<<1); 32 else if(lt > mid) return query(lt,rt,v<<1|1); 33 else return min(query(lt,mid,v<<1),query(mid+1,rt,v<<1|1)); 34 } 35 void update(int lt,int rt,int v){ 36 if(tree[v].lt == tree[v].rt){ 37 tree[v].minVal = d[tree[v].lt]; 38 return; 39 } 40 int mid = (tree[v].lt+tree[v].rt)>>1; 41 if(u[rt] <= mid) update(lt,rt,v<<1); 42 else if(u[lt] > mid) update(lt,rt,v<<1|1); 43 else{ 44 int i; 45 for(i = lt; u[i] <= mid; i++); 46 update(lt,i-1,v<<1); 47 update(i,rt,v<<1|1); 48 } 49 tree[v].minVal = min(tree[v<<1].minVal,tree[v<<1|1].minVal); 50 } 51 int main(){ 52 int n,m,i,j,len,temp; 53 char str[100]; 54 while(~scanf("%d%d",&n,&m)){ 55 for(i = 1; i <= n; i++) 56 scanf("%d",d+i); 57 build(1,n,1); 58 for(i = 0; i < m; i++){ 59 scanf("%s",str); 60 len = strlen(str); 61 for(cnt = j = 0; j < len;){ 62 if(str[j] < ‘0‘ || str[j] > ‘9‘) {j++;continue;} 63 temp = 0; 64 while(j < len && str[j] >= ‘0‘ && str[j] <= ‘9‘) {temp = temp*10 + (str[j]-‘0‘);j++;} 65 u[cnt++] = temp; 66 } 67 if(str[0] == ‘q‘){ 68 printf("%d\n",query(u[0],u[1],1)); 69 }else{ 70 temp = d[u[0]]; 71 for(cnt--,j = 0; j < cnt; j++) 72 d[u[j]] = d[u[j+1]]; 73 d[u[j]] = temp; 74 update(0,cnt,1); 75 } 76 } 77 } 78 return 0; 79 }
C. RMQ with Shifts