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.
Warning: The dataset is large, better to use faster I/O methods.
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
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; }