1. 程式人生 > >HDU1754——I Hate It(線段樹)

HDU1754——I Hate It(線段樹)

I Hate It

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


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解題思路: 簡單的線段樹問題,直接套模版就可以,這道題實現的是區間最大,單點更新問題。 首先建樹,每個節點的值為該子樹的最大值,葉子為每個學生的分數,找區間最大隻需要找到該區間範圍對應的樹即可,然後比較求出最大值;單點更新只需找到該點的位置,然後遞迴更新該節點的雙親,使雙親始終為該子樹的最大值。跟著模版多做幾道題就好。程式碼實現:
#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <cstring>
#include <queue>
#include <map>
#include <vector>
#include <set>
#include <cmath>
#include <algorithm>

using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn = 200000 + 10;
int sum[maxn<<2];
int N, M;

void pushup(int rt)
{
    sum[rt] = max( sum[rt<<1], sum[rt<<1|1] );
}

void build(int l, int r, int rt)
{
    if( l==r )
    {
        scanf("%d",&sum[rt]);
        return ;
    }
    int m = (l+r)>>1;
    build(lson);
    build(rson);
    pushup(rt);
}

int query(int L, int R, int l, int r, int rt)
{
    if( l>=L && r<=R )
    {
        return sum[rt];
    }
    int MAX_DATE = 0;

    int m = (l+r)>>1;
    if( L <= m )
        MAX_DATE = max(MAX_DATE, query( L, R, lson));
    if( R > m )
        MAX_DATE = max(MAX_DATE, query( L, R, rson));
    return MAX_DATE;
}

void update(int S, int num, int l, int r, int rt)
{
    if( r == l )
    {
        sum[rt] = num;
        return ;
    }
    int m = (l+r)>>1;
    if( S <= m )
        update( S, num, lson);
    else
        update( S, num, rson);
    pushup(rt);
}

int main()
{
    char op[2];
    int x, y;
    while( scanf("%d%d",&N,&M) !=EOF )
    {
        memset(sum, 0, sizeof(sum));
        build(1, N, 1);
        for( int i=0; i<M; i++ )
        {
            scanf("%s%d%d", op,&x, &y);
            if( 'Q' == op[0] )
            {
                printf("%d\n", query(x, y, 1, N, 1));
            }
            else
            {
                update(x, y, 1, N, 1);
            }
        }
    }
    return 0;
}