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
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 ( 1n
100, 000, 1
q
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
线段树,模拟即可,水题
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<set> #include<queue> #include<string> #include<cmath> #include<fstream> #include<iomanip> using namespace std; #define LL long long #define lson rt<<1, l, m #define rson rt<<1|1, m, r #define MAXN 110000 int ans[MAXN<<2], n, q, a[MAXN]; void push_up(int rt){ ans[rt] = min(ans[rt<<1], ans[rt<<1|1]); } void build(int rt, int l, int r){ if(l+1 == r){ scanf(" %d", &a[l]); ans[rt] = a[l]; return; } int m = l + r >> 1; build(lson); build(rson); push_up(rt); } void update(int rt, int l, int r, int x){ if(l+1 == r){ ans[rt] = a[x]; return; } int m = l + r >> 1; if(x < m) update(lson, x); else update(rson, x); push_up(rt); } #define INF 11111111 int query(int rt, int l, int r, int cl, int cr){ if(cl<=l && cr >=r) return ans[rt]; int m = l + r >> 1, ret=INF; if(m > cl) ret=min(ret, query(lson, cl, cr)); if(m < cr) ret=min(ret, query(rson, cl, cr)); return ret; } int main(){ // freopen("C:\Users\Administrator\Desktop\in.txt","r",stdin); scanf(" %d %d", &n, &q); build(1, 1, n+1); while(q--){ char ch, tc; int t[40], len=0; scanf(" %c", &ch); while((getchar())!='('); while(true){ scanf(" %d%c", &t[len++], &tc); if(tc==')') break; } if(ch == 'q' && t[0] > t[1]) swap(t[0], t[1]); if(ch == 'q') printf("%d ", query(1, 1, n+1, t[0], t[1]+1)); else{ int tmp = a[t[0]]; for(int i=1; i<len; i++) a[t[i-1]]=a[t[i]]; a[t[len-1]] = tmp; for(int i=0; i<len; i++) update(1, 1, 1+n, t[i]); } } return 0; }