爱爬山的小Z

E - 爱爬山的小Z

Time Limit:  6000/3000MS (Java/Others)     Memory Limit:  128000/64000KB (Java/Others)
Submit  Status

Problem Description

从前有一座ACdream王国,这个王国被群山环绕,因此外面的人很少有人知道它的存在。

这个王国里,有一位很喜欢爬山的小伙子,小Z,他觉得在爬山的过程中,能够有一种征服自然的感觉。

小Z定义一条登山路径的困难程度,为整个路径中经过的山的高度的最大值。

然而ACdream王国是一个很神奇的王国,山的高度经常会改变,因此小Z不得不随时重新测量山的高度。

小Z疲惫于测量高度,所以没有精力考虑每条路径的困难程度了。所以想请你帮忙。

Input

多组数据,每组数据首先是一个整数N(N<=100000),表示围绕着ACdream王国的山的数量

接下来是N个整数,表示每一座山的高度h[i](1<=h[i]<=100000),编号从1开始,注意第1座山和第N座山相邻。

接下来是一个整数Q(Q<=100000),表示小Z进行的操作

接下来是Q行,每行是三个整数a,b,c,如果a为0,则代表小Z重新测量第b座山,高度为c,(1<=b<=N,1<=c<=100000)

如果a为1,则代表小Z想知道从b到c的最小困难程度。(1<=b,c<=N)

Output

对于每一次小Z的询问,输出一个整数,表示路径上的最小困难程度。

Sample Input

6
1 10 2 20 3 30
3
1 1 5
0 6 3
1 1 5

Sample Output

20
3

Hint

故事是这样的,小Z养了一只兔子和一只乌龟,受到小Z的兴趣的影响,兔子和乌龟也喜欢爬山~

有一天,兔子和乌龟要比赛,规定从1号山作为起点,5号山作为终点

小Z说“预备,起~”后,聪明的兔子就沿着1-2-3-4-5的顺序拼命跑。

这是专业坑队友的小Z发现自己的地图的6号山的高度写错了,多写了一个0,赶紧改了~

然而这时兔子已经不知道去哪了,于是乌龟就慢条斯理地沿着1-6-5散步,最终乌龟获得胜利~!

《ACdream童话故事——龟兔赛跑》完


题目大意:给出一个数列,两头相连,求区间最大值,包括正着的区间和逆着的区间。


分析:线段树略微变形一下。正着的区间就是RMQ,逆着的分成两段,从区间左端点到1,和从区间右端点到n。


代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 200010;
int Max[4*maxn];

void PushUP(int root) {
    Max[root] = max(Max[2*root+1], Max[2*root+2]);
    return;
}

void Update(int root, int l, int r, int p, int c) {
    if(l == r) {
        Max[root] = c;
        return;
    }
    int m = (l+r)>>1;
    if(p <= m) Update(2*root+1, l, m, p, c);
    else Update(2*root+2, m+1, r, p, c);
    PushUP(root);
    return;
}

int Query(int root, int l, int r, int L, int R) {
    if(L <= l && r <= R) {
        return Max[root];
    }
    int m = (l+r)>>1;
    int ans = 0;
    if(L <= m) ans = max(ans, Query(2*root+1, l, m, L, R));
    if(m < R) ans = max(ans, Query(2*root+2, m+1, r, L, R));
    return ans;
}

void Build(int root, int l, int r) {
    if(l == r) {
        scanf("%d", &Max[root]);
        return;
    }
    int m = (l+r)>>1;
    Build(2*root+1, l, m);
    Build(2*root+2, m+1, r);
    PushUP(root);
    return;
}

int main() {
    int n;
    while(~scanf("%d", &n)) {
        if(n == 0) continue;
        Build(0, 1, n);
        int m, op, a, b;
        scanf("%d", &m);
        while(m--) {
            scanf("%d%d%d", &op, &a, &b);
            if(op){
                if(a > b) swap(a, b);
                printf("%d\n", min(Query(0, 1, n, a, b), max(Query(0, 1, n, 1, a), Query(0, 1, n, b, n))));
            }
            else Update(0, 1, n, a, b);
        }
    }
    return 0;
}








你可能感兴趣的:(爱爬山的小Z)