【题意】

求你查询某一段的最小值,但是还有一个shift操作,将(a0, a1, a2, a3..ak)这个K个位置的数字互相对掉,例如a0位置的值变成a1,a1位置的值变成a2...ak位置的值变成a0.

【解题方法】单点更新,没什么说的,看代码。

【AC code】

#include <bits/stdc++.h>
using namespace std;
const int maxn=100010;
char s[1000];
int a[maxn];
int b[100];
int num[100];
struct node{
    int l,r,minn;
}Tree[maxn<<2];
void pushup(int rt)
{
    Tree[rt].minn=min(Tree[rt*2].minn,Tree[rt*2+1].minn);
}
void Build(int l,int r,int rt)
{
    Tree[rt].l=l,Tree[rt].r=r;
    if(l==r){
        Tree[rt].minn=a[l];
        return ;
    }
    int mid=(l+r)/2;
    Build(l,mid,rt*2);
    Build(mid+1,r,rt*2+1);
    pushup(rt);
}
void update(int pos,int val,int rt)
{
    if(Tree[rt].l==pos&&Tree[rt].r==pos){
        Tree[rt].minn=val;
        return ;
    }
    int mid=(Tree[rt].l+Tree[rt].r)/2;
    if(pos<=mid) update(pos,val,rt*2);
    else         update(pos,val,rt*2+1);
    pushup(rt);
}
int queryans(int L,int R,int rt)
{
    if(Tree[rt].l==L&&Tree[rt].r==R){
        return Tree[rt].minn;
    }
    int mid=(Tree[rt].l+Tree[rt].r)/2;
    if(R<=mid) return queryans(L,R,rt*2);
    else if(L>mid) return queryans(L,R,rt*2+1);
    else{
        return min(queryans(L,mid,rt*2),queryans(mid+1,R,rt*2+1));
    }
}

int main()
{
    int n,q;
    while(~scanf("%d%d",&n,&q))
    {
        for(int i=1; i<=n; i++) scanf("%d",&a[i]);
        Build(1,n,1);
        //puts("success");
        for(int i=0; i<q; i++){
            scanf("%s",s);
//            if(s[0]=='q'){
//                int x=0,y=0;
//                for(int i=0; i<(int)strlen(s); i++) {
//                    if(isdigit(s[i])){
//                        if(x==0) {x=s[i]-'0';continue;}
//                        if(y==0) {y=s[i]-'0';break;}
//                    }
//                }
//                cout<<x<<" "<<y<<endl;
//                if(x>y) swap(x,y);
//                printf("%d\n",queryans(x,y,1));
//            }else{
//                memset(b,0,sizeof(b));
//                int cnt=0;
//                for(int i=0; i<(int)strlen(s); i++){
//                    if(isdigit(s[i])) b[cnt++]=s[i]-'0';
//                }
//                for(int i=0; i<cnt; i++) cout<<b[i]<<" ";cout<<endl;
//                for(int i=0; i<cnt; i++) update()
//            }
            int cnt=0;
            memset(b,0,sizeof(b));
            bool flag=0;
            b[0]=0;
            for(int i=0; i<(int)strlen(s); i++){
                if(isdigit(s[i])){
                    b[cnt]=b[cnt]*10+s[i]-'0';
                    flag=1;
                }
                else if(flag){
                    b[++cnt]=0;
                }
            }
            if(s[0]=='q'){
                printf("%d\n",queryans(b[0],b[1],1));
            }else{
                for(int i=0; i<cnt; i++){
                    num[i]=a[b[i]];
                }
                for(int i=0; i<cnt; i++){
                    if(i+1<cnt) a[b[i]]=num[i+1];
                    else        a[b[i]]=num[0];
                    update(b[i],a[b[i]],1);
                }
            }
        }
    }
}