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
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
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
n
100, 000, 1
q
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;
}

浙公网安备 33010602011771号