uva 12299, 线段树

 

  RMQ with Shifts 

In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for each query (L, R) (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(i1, i2, i3,..., ik)(i1 < i2 < ... < ik, k > 1)

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

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.

 

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

线段树,模拟即可,水题
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<string>
#include<cmath>
#include<fstream>
#include<iomanip>

using namespace std;

#define LL long long
#define lson rt<<1, l, m
#define rson rt<<1|1, m, r
#define MAXN 110000
int ans[MAXN<<2], n, q, a[MAXN];

void push_up(int rt){ ans[rt] = min(ans[rt<<1], ans[rt<<1|1]); }

void build(int rt, int l, int r){
    if(l+1 == r){
        scanf(" %d", &a[l]);
        ans[rt] = a[l];
        return;
    }
    int m = l + r >> 1;
    build(lson);
    build(rson);
    push_up(rt);
}

void update(int rt, int l, int r, int x){
    if(l+1 == r){
        ans[rt] = a[x];     return;
    }
    int m = l + r >> 1;
    if(x < m) update(lson, x);
    else update(rson, x);
    push_up(rt);
}
#define INF 11111111
int query(int rt, int l, int r, int cl, int cr){
    if(cl<=l && cr >=r) return ans[rt];
    int m = l + r >> 1, ret=INF;
    if(m > cl) ret=min(ret, query(lson, cl, cr));
    if(m < cr) ret=min(ret, query(rson, cl, cr));
    return ret;
}

int main(){
//    freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
    scanf(" %d %d", &n, &q);
    build(1, 1, n+1);
    while(q--){
        char ch, tc;
        int t[40], len=0;
        scanf(" %c", &ch);
        while((getchar())!='(');
        while(true){
            scanf(" %d%c", &t[len++], &tc);
            if(tc==')') break;
        }
        if(ch == 'q' && t[0] > t[1]) swap(t[0], t[1]);
        if(ch == 'q') printf("%d\n", query(1, 1, n+1, t[0], t[1]+1));
        else{
            int tmp = a[t[0]];
            for(int i=1; i<len; i++)
                a[t[i-1]]=a[t[i]];
            a[t[len-1]] = tmp;
            for(int i=0; i<len; i++)
                update(1, 1, 1+n, t[i]);
        }
    }
    return 0;
}

 

posted @ 2013-11-07 16:51  Ramanujan  阅读(136)  评论(0编辑  收藏  举报