关闭

HDU 1754 I hate it

标签: hdu-线段树
176人阅读 评论(0) 收藏 举报
分类:
/*B - I Hate It
Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
Submit

Status
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 
 */

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

int N,M;
const int SIZE = 200010,INTMIN = -2147483647;
int g_students[SIZE],g_segTree[SIZE*4];//定义四倍空间节点

//node对应区间[begin,end]。node是g_segTree,begin~end是g_students
void Build(int node,int begin,int end){
    if(begin==end){
        g_segTree[node] = g_students[begin];
        return ;
    }
    int mid = (begin + end) >> 1;
    Build(2*node,begin,mid);
    Build(2*node+1,mid+1,end);
    g_segTree[node] = max(g_segTree[2*node],g_segTree[2*node+1]);
    return ;    
}

int Query(int node,int begin,int end,int q_left,int q_right){
    if(q_left>end || q_right<begin) return INTMIN ;
    if(q_left<=begin && end <= q_right) return g_segTree[node];
    int mid = begin + ((end-begin)>>1);
    int lson = Query(node*2,begin,mid,q_left,q_right);
    int rson = Query(node*2+1,mid+1,end,q_left,q_right);
    return max(lson,rson);
}
/*
进行节点的更新,同时注意对树的维护,因为一个节点的改变会涉及到一部分
当C为'U'的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。 
要时刻明确node是线段树上的节点,即g_segTree的元素,其对应的是g_students上的区间[begin,end],而题目中输
入的更新学生ID对应的是g_students中的元素下标
*/
void Update(int node,int begin,int end,int indexer,int data){
    if(begin==end && indexer==begin){//单节点更新,
        g_segTree[node] = data;
        return ;
    }
    //找到待更新的子树
    int mid = (begin+end) >> 1;//区间分割
    if(indexer <= mid) Update(2*node,begin,mid,indexer,data);
    else Update(2*node+1,mid+1,end,indexer,data);
    g_segTree[node] = max(g_segTree[2*node],g_segTree[2*node+1]);
    return ;
}

int main(){
    while(scanf("%d %d",&N,&M)!=EOF){
        getchar();
        for(int i=1;i<=N;i++) scanf("%d",g_students+i);
        Build(1,1,N);
        char C;
        int A,B;
        while(M--){
            getchar();
            scanf("%c %d %d",&C,&A,&B);
            if(C=='Q'){
                //查询区间为[A,B],A应该<=B
                if(A>B) swap(A,B);//但这一句只能写到if内,,不能写在上面,因为对于Update操作,
                int res = Query(1,1,N,A,B);//A是节点,B是待更新的成绩,A,B大小关系不确定是理所应当的
                printf("%d\n", res);
            }//注意
            else if(C=='U') Update(1,1,N,A,B);
        }
    }
    return 0;
}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:37756次
    • 积分:1091
    • 等级:
    • 排名:千里之外
    • 原创:67篇
    • 转载:3篇
    • 译文:2篇
    • 评论:8条
    文章分类
    最新评论