UVa12299 - RMQ with Shifts

题目大意

给定一个长度为n的序列A,可以对其进行一下两种操作:

1、query (L, R) 查询区间[L,R]的最小值

2、shift(i1, i2, i3,..., ik)(i1 < i2 < ... < ik, k > 1)   把元素A[i1],A[i2],…,A[ik]循环移动

题解

区间最小值查询+单点修改。。。水题。。。。

代码:

#include<iostream>

#include<cstdio>

#include<string>

#include<cstring>

#include<algorithm>

#include<vector>

using namespace std;

#define MAXN 100005

#define lson l,m,s<<1

#define rson m+1,r,s<<1|1

#define INF 0x7fffffff

int minv[MAXN<<2],val[MAXN];

vector<int> V,A;

void PushUp(int s)

{

        minv[s]=min(minv[s<<1],minv[s<<1|1]);

}

void build(int l,int r,int s)

{

        if(l==r) {

                scanf("%d",&val[l]);

                minv[s]=val[l];

                return;

        }

        int m=(l+r)>>1;

        build(lson);

        build(rson);

        PushUp(s);

}

void update(int p,int d,int l,int r,int s)

{

        if(l==r) {

                val[l]=d;

                minv[s]=d;

                return;

        }

        int m=(l+r)>>1;

        if(p<=m) update(p,d,lson);

        else

                update(p,d,rson);

        PushUp(s);

}

int query(int ql,int qr,int l,int r,int s)

{

        if(ql<=l&&r<=qr)

                return minv[s];

        int m=(l+r)>>1,ans=INF;

        if(ql<=m) ans=min(ans,query(ql,qr,lson));

        if(qr>m) ans=min(ans,query(ql,qr,rson));

        return ans;

}

int main(void)

{

        int n,m,len;

        char s[45];

        while(~scanf("%d%d",&n,&m)) {

                build(1,n,1);

                while(m--) {

                        int a,b;

                        scanf("%s",s);

                        len=strlen(s);

                        if(s[0]=='q') {

                                a=0;

                                b=0;

                                int i=4;

                                while(s[i]!=',') {

                                        if(isdigit(s[i]))

                                                a=a*10+s[i]-'0';

                                        i++;

                                }

                                while(i<len) {

                                        if(isdigit(s[i]))

                                                b=b*10+s[i]-'0';

                                        i++;

                                }

                                printf("%d\n",query(a,b,1,n,1));

                        } else {

                                int i=4;

                                V.clear();

                                A.clear();

                                while(i<len) {

                                        int a=0;

                                        while(s[i]!=','&&s[i]!=')') {

                                                if(isdigit(s[i]))

                                                        a=a*10+s[i]-'0';

                                                i++;

                                        }

                                        i++;

                                        V.push_back(a);

                                        A.push_back(val[a]);

                                }

                                int b=A[0];

                                A.erase(A.begin());

                                A.push_back(b);

                                for(int i=0; i<V.size(); i++)

                                        update(V[i],A[i],1,n,1);

                        }

                }

        }

        return 0;

}

你可能感兴趣的:(with)