题目

Description

很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。
这让很多学生很反感。

不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。

Input

本题目包含多组测试,请处理到文件结束。
在每个测试的第一行,有两个正整数 N 和 M ( 0<N<=200000,0<M<5000 ),分别代表学生的数目和操作的数目。
学生ID编号分别从1编到N。
第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数代表ID为i的学生的成绩。
接下来有M行。每一行有一个字符 C (只取'Q'或'U') ,和两个正整数A,B。
当C为'Q'的时候,表示这是一条询问操作,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。
当C为'U'的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。

Output

对于每一次询问操作,在一行里面输出最高成绩。

Sample Input

5 6
1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 2 9
Q 1 5

Sample Output

5
6
5
9

题解

线段树单点更新问题

模板题,注意数组开的大小

代码

/*
By:OhYee
Github:OhYee
Blog:http://www.oyohyee.com/
Email:oyohyee@oyohyee.com

かしこいかわいい?
エリーチカ!
要写出来Хорошо的代码哦~
*/
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <bitset>
#include <functional>

using namespace std;

typedef long long LL;

const int INF = 0x7FFFFFFF;
const double eps = 1e-10;

int kase = 1;

int ST[(2 << 18) + 1];
int Size;

int Query(int a,int b) {
    int l = Size + a - 1;
    int r = Size + b - 1;

    int Max = 0;
    while(r - l > 1) {
        if(l & 1) {
            Max = max(Max,ST[l]);
            l = (l >> 1) + 1;
        } else {
            l >>= 1;
        }
        if(r & 1) {
            r >>= 1;
        } else {
            Max = max(Max,ST[r]);
            r = (r >> 1) - 1;
        }

    }
    if(l == r)
        Max = max(Max,ST[l]);
    else
        Max = max(Max,max(ST[l],ST[r]));
    return Max;
}

void Update(int a,int b) {
    int pos = Size + a - 1;
    ST[pos] = b;
    pos >>= 1;
    while(pos != 0) {
        ST[pos] = max(ST[pos << 1],ST[(pos << 1) | 1]);
        pos >>= 1;
    }

}

void Build() {
    for(int i = 1;i < Size;i++)
        ST[i] = 0;
    for(int i = Size - 1;i >= 1;i--)
        ST[i] = max(ST[i << 1],ST[(i << 1) | 1]);
}

bool Do() {
    int n,m;
    if(!(cin >> n >> m))
        return false;

    Size = 1;
    while(Size < n)
        Size <<= 1;

    for(int i = 1;i < Size;i++) {
        if(i <= n)
            cin >> ST[Size + i - 1];
        else
            ST[Size + i - 1] = 0;
    }

    Build();

    while(m--) {
        char c;
        int a,b;
        cin >> c >> a >> b;
        if(c == 'U')
            Update(a,b);
        else
            cout << Query(a,b) <<endl;
    }
    return true;
}

int main() {
    cin.tie(0);
    cin.sync_with_stdio(false);

    while(Do());

    return 0;
}