I Hate It(线段树基础)

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 45287    Accepted Submission(s): 17773


Problem 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
Hint
Huge input,the C function scanf() will work better than cin
 
/*times memy
  889ms 8584k 
    by orc
    */
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 200005;
int n,m;
struct node{
    int lt,rt;
    int mx;
}tree[4 * N];
int a[N];
void build(int l,int r,int v)
{
    tree[v].lt = l;
    tree[v].rt = r;
    if(l == r) {tree[v].mx = a[l];return;}
    int m = (l + r) >> 1;
    build(l,m,2 * v);
    build(m + 1,r,2 * v + 1);
    tree[v].mx = max(tree[2 * v].mx,tree[2 * v + 1].mx);
}
void update(int v,int k,int val)//直接暴力更新
{
    if(tree[v].lt == tree[v].rt)
    {
        if(tree[v].lt == k)
        tree[v].mx = val;
        return;
    }
    int m = (tree[v].lt + tree[v].rt) >> 1;
    if(k <= m) update(v * 2,k,val);//更新左子树
    else update(v * 2 + 1,k,val);//更新右子树
    tree[v].mx = max(tree[v << 1].mx,tree[(v << 1) + 1].mx);
    //else tree[v >> 1].mx = max(tree[v].mx,tree[v + 1].mx);
}
int query(int v,int l,int r)
{
    if(l == tree[v].lt && r == tree[v].rt) return tree[v].mx;
    int m = (tree[v].lt + tree[v].rt) >> 1;
    if(r <= m) query(v * 2,l,r);
    else if(l > m) query(v * 2 + 1,l ,r);
    else{
        return max(query(v * 2,l,m),query(v * 2 + 1,m + 1,r));
    }
}
void solve()
{
    char C;
    int A ,B;
    for(int i = 1; i <= n; ++i)
    cin >> a[i];
    build(1,n,1);
    while(m--)
    {
        cin >> C;
        cin >> A >> B;
        if(C == 'Q')
        {
            cout << query(1,A,B) <<endl;
            continue;
        }
        else update(1,A,B);
    }
}
int main()
{
    ios::sync_with_stdio(0);
    while(cin >> n >> m) solve();
    return 0;
}
Author
linle
原文地址:https://www.cnblogs.com/orchidzjl/p/4436370.html