12299 - RMQ with Shifts

来源:互联网 发布:linux find exec用法 编辑:程序博客网 时间:2024/05/27 00:52
没什么特别的地方,比较水的题//#pragma comment(linker, "/STACK:1024000000,1024000000")#include <iostream>#include <stack>#include <queue>#include <cstdio>#include <cstdlib>#include <cmath>#include <set>#include <vector>#include <cstring>#include <algorithm>#define INF 0x3fffffff#define N 1000010#define M (1000000 << 2)#define LL long long#define mod 95041567using namespace std;struct Node{    int rt, l, r, MIN;};Node p[M + 10];int cnt, MIN;int arr[N][2];int num[N];char str[35];void build(int rt, int l, int r){    if(l == r){        scanf("%d", &arr[l][0]);        p[rt].MIN = arr[l][0];    //    p[rt].l = p[rt].r = l;        //p[rt].rt = rt;        arr[l][1] = rt;        return;    }    int mid = (r - l) / 2 + l;    int lc = rt << 1;    int rc = lc + 1;    build(lc, l, mid);    build(rc, mid + 1, r);    p[rt].MIN = min(p[lc].MIN, p[rc].MIN);  //  p[rt].l = l, p[rt].r = r;  //  p[rt].rt = rt;  //  printf("%d %d %d %d\n", rt, p[rt].MIN, l, r);}void solve(){    int len = strlen(str);    for(int i = 0; i < len; ) {        if(isdigit(str[i])) {            num[cnt] = 0;            for(int j = i; j < len; ++ j)                if(isdigit(str[j]))                    num[cnt] = num[cnt] * 10 + str[j] - '0';                else {                    ++ cnt;                    i = j + 1;                    break;                }        }        else ++ i;    }}void query(int rt, int l, int r, int L, int R){   // printf("%d %d %d %d\n", l, r, L, R);    if(L <= l && R >= r){        MIN = min(MIN, p[rt].MIN);     //   printf("%d ++\n", p[rt].MIN);        return;    }    int mid = (r - l) / 2 + l;    int lc = rt << 1;    int rc = lc + 1;    if(mid < L) query(rc, mid + 1, r, L, R);    else if(R <= mid) query(lc, l, mid, L, R);    else {        query(lc, l, mid, L, mid);        query(rc, mid + 1, r, mid + 1, R);    }}void update(int rt){    int rl = rt / 2;    int lc = rl << 1;    int rc = lc + 1;    int m = min(p[lc].MIN, p[rc].MIN);    if(m != p[rl].MIN){        p[rl].MIN = m;        if(rl == 1) return;        update(rl);    }}int main(){   // freopen("in.txt","r",stdin);    int n, m;    while(scanf("%d %d", &n, &m) != EOF){        build(1, 1, n);        for(int i = 0; i < m; ++ i){            scanf("%s", str);            cnt = 0;            solve();            if(str[0] == 'q'){                MIN = INF;                int l = min(num[0], num[1]), r = max(num[0], num[1]);                query(1, 1, n, l, r);                printf("%d\n", MIN);            }            else{                for(int i = 1; i < cnt; ++ i){                    swap(arr[num[i]][0], arr[num[i - 1]][0]);                    p[arr[num[i - 1]][1]].MIN = arr[num[i - 1]][0];                    update(arr[num[i - 1]][1]);                }                p[arr[num[cnt - 1]][1]].MIN = arr[num[cnt - 1]][0];                update(arr[num[cnt - 1]][1]);              /*  for(int i = 0; i <= n; ++ i)                    printf("%d ", arr[i][0]);                puts("");*/            }        }    }    return 0;}