描述
In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for each query (L, R) (L<=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(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}.
输入
There will be only one test case, beginning with two integers n, q (1<=n<=100,000, 1<=q<=120,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.
输出
For each query, print the minimum value (rather than index) in the requested range.
样例输入
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)
样例输出
1
4
6
题意
给你N个数,有两个操作
1.查询区间最小
2.给定几个位置,循环左移
题解
可以看出循环左移的区间不是很大,那么直接拿线段树暴力更新
代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 #define ll long long 5 6 const int maxn=1e5+5; 7 8 int n,q; 9 int Min[maxn<<2]; 10 11 void build(int l,int r,int rt) 12 { 13 if(l==r) 14 { 15 scanf("%d",&Min[rt]); 16 return; 17 } 18 int mid=(l+r)>>1; 19 build(l,mid,rt<<1); 20 build(mid+1,r,rt<<1|1); 21 Min[rt]=min(Min[rt<<1],Min[rt<<1|1]); 22 } 23 24 void update(int L,int c,int l,int r,int rt) 25 { 26 if(l==r) 27 { 28 Min[rt]=c; 29 return; 30 } 31 int mid=(l+r)>>1; 32 if(L<=mid)update(L,c,l,mid,rt<<1); 33 else update(L,c,mid+1,r,rt<<1|1); 34 Min[rt]=min(Min[rt<<1],Min[rt<<1|1]); 35 } 36 37 int query(int L,int R,int l,int r,int rt) 38 { 39 if(L<=l&&r<=R) 40 return Min[rt]; 41 int mid=(l+r)>>1,ans=0x3f3f3f3f; 42 if(L<=mid)ans=min(ans,query(L,R,l,mid,rt<<1)); 43 if(R>mid)ans=min(ans,query(L,R,mid+1,r,rt<<1|1)); 44 return ans; 45 } 46 47 int main() 48 { 49 scanf("%d%d",&n,&q); 50 build(1,n,1); 51 for(int i=0;i<q;i++) 52 { 53 getchar(); 54 int pre,cur; 55 if(getchar()=='s') 56 { 57 while(getchar()!='('); 58 scanf("%d",&pre); 59 int first=query(pre,pre,1,n,1); 60 while(getchar()!=')') 61 { 62 scanf("%d",&cur), 63 update(pre,query(cur,cur,1,n,1),1,n,1); 64 pre=cur; 65 } 66 update(pre,first,1,n,1); 67 } 68 else 69 { 70 while(getchar()!='('); 71 scanf("%d,%d)",&pre,&cur); 72 printf("%d ",query(pre,cur,1,n,1)); 73 } 74 } 75 return 0; 76 }