RMQ with Shifts

RMQ with Shifts

In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for each query (LR)(L$ \le$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( i 1i 2i 3,...,  i k)( i 1 <  i 2 < ... <  i kk > 1)

we do a left ``circular shift" of  A[i1] A[i2] , ...,  A[ik] .

For example, if A={6, 2, 4, 85, 1, 4}, then shift(2, 4, 5, 7) yields {68, 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$ \le$n$ \le$100, 000 1$ \le$q$ \le$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



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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值