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

posted on 2013-06-03 15:34  仗剑奔走天涯  阅读(284)  评论(0编辑  收藏  举报

导航