UVA-12299 RMQ with Shift(線分樹)
2237 ワード
テーマリンク:https://vjudge.net/problem/UVA-12299
考え:裸の線分樹は、移動時に最大30個を超えないので、直接に注文して更新すればいいです.その後、区間で調べてみます.答えの間には空行があります.
考え:裸の線分樹は、移動時に最大30個を超えないので、直接に注文して更新すればいいです.その後、区間で調べてみます.答えの間には空行があります.
#include
#define lson num << 1
#define rson num << 1 | 1
#define MAXN 100005
using namespace std;
struct node
{
int l,r;
int Min;
}tree[MAXN << 2];
int a[MAXN],val[MAXN];
void pushup(int num)
{
tree[num].Min = min(tree[lson].Min,tree[rson].Min);
}
void build(int num,int l,int r)
{
tree[num].l = l;
tree[num].r = r;
if(l == r) {
tree[num].Min = a[l];
return;
}
int mid = (tree[num].l + tree[num].r) >> 1;
build(lson,l,mid);
build(rson,mid + 1,r);
pushup(num);
}
int query(int num,int l,int r)
{
if(tree[num].l == l && tree[num].r == r) {
return tree[num].Min;
}
int mid = (tree[num].l + tree[num].r) >> 1;
if(r <= mid) return query(lson,l,r);
else if(l > mid) return query(rson,l,r);
else return min(query(lson,l,mid),query(rson,mid + 1,r));
}
void update(int num,int pos)
{
if(tree[num].l == pos && tree[num].r == pos) {
tree[num].Min = a[pos];
return;
}
int mid = (tree[num].l + tree[num].r) >> 1;
if(pos <= mid) update(lson,pos);
else update(rson,pos);
pushup(num);
}
int main(void)
{
int n,q,len,l,r,i,j;
char op[50];
int pos[50],cnt,end;
scanf("%d %d",&n,&q);
for(i = 1; i <= n; i++) {
scanf("%d",&a[i]);
}
build(1,1,n);
while(q--) {
scanf("%s",op);
len = strlen(op);
if(op[0] == 'q') {
l = 0,r = 0;
for(i = 6; i < len; i++) {
if(op[i] == ',') break;
l = l * 10 + op[i] - '0';
}
for(j = i + 1; j < len - 1; j++) {
r = r * 10 + op[j] - '0';
}
printf("%d
",query(1,l,r));
}
else {
cnt = 0;
memset(pos,0,sizeof(pos));
for(i = 6; i < len - 1; i++) {
if(op[i] == ',') cnt++;
else pos[cnt] = pos[cnt] * 10 + op[i] - '0';
}
for(i = 0; i <= cnt; i++) {
val[pos[i]] = a[pos[i]];
}
for(int i = 0; i <= cnt; i++) {
a[pos[i]] = val[pos[(i + 1) % (cnt + 1)]];
update(1,pos[i]);
}
}
}
return 0;
}
/*
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)
*/