RMQ with Shifts
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
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



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
直接单点更新
下面是AC代码:
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 100000+10;
int a[maxn];
int index[maxn];
struct node{
int l,r;
int min,val;
}T[maxn<<2];
void build(int id,int l,int r){
T[id].l=l;T[id].r=r;
if(l==r) { T[id].min=T[id].val=a[l]; return ; }
int m=(l+r)>>1;
build(id<<1,l,m); build(id<<1|1,m+1,r);
T[id].min=min(T[id<<1].min,T[id<<1|1].min);
}
void update(int id,int l,int r,int val){
if(T[id].l==l&&T[id].r==r){
T[id].min=T[id].val=val; return ;
}
int m=(T[id].l+T[id].r)>>1;
if(m>=r) update(id<<1,l,r,val);
else update(id<<1|1,l,r,val);
T[id].min=min(T[id<<1].min,T[id<<1|1].min);
}
int query(int id,int l,int r){
if(T[id].l==l&&T[id].r==r){
return T[id].min;
}
int m=(T[id].l+T[id].r)>>1;
if(m>=r) return query(id<<1,l,r);
else if(l>m) return query(id<<1|1,l,r);
else{
return min(query(id<<1,l,m),query(id<<1|1,m+1,r));
}
}
int main(){
freopen("data.in","r",stdin);
// freopen("data.out","w",stdout);
int n,q,l,r; char str[100];
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,1,n);
for(int i=0;i<q;i++){
scanf("%s",str);
if(str[0]=='q'){
sscanf(str+5,"(%d,%d)",&l,&r);
printf("%d\n",query(1,l,r));
}
else{
int k,l=0,t=0;
for(k=0;str[k];k++) if(str[k]=='(') break;
for(int j=k+1;str[j];j++){
while(str[j]!=','&&str[j]!=')'){
t=t*10+str[j]-'0';
j++;
}
index[l++]=t;
t=0;
}
t=a[index[0]];
for(int k=0;k<l;k++){
if(k==0) update(1,index[l-1],index[l-1], a[index[0] ]);
else
update(1,index[k-1],index[k-1], a[index[k] ]) ;
}
for(int k=0;k<l-1;k++){
a[ index[k]]=a[ index[k+1]];
}
a[ index[l-1]]=t;
}
}
return 0;
}