线段树入门第一题! I Hate It HDU - 1754

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

不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
Input本题目包含多组测试,请处理到文件结束。 
在每个测试的第一行,有两个正整数 N 和 M ( 0 学生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
#include
#include
using namespace std;
const int maxn = 200000+10;
const int NINF = 0xc0c0c0c0;
int n,m,k;
char action;
int grade[maxn*2],segtree[maxn*2];   //grade 要设成两倍,segtree 设两倍也可以过,有点迷。。
void build(int l,int r,int pos){
    if(r - l == 1){
        segtree[pos] = grade[l];
        return;
    } 
    int mid = (l+r)/2;
    build(l,mid,pos*2+1);
    build(mid,r,pos*2+2);
    segtree[pos] = max(segtree[pos*2+1],segtree[pos*2+2]);
}
void update(int id,int val){
    id += k-1;       //找到对应叶节点
    segtree[id] = val;
    while(id > 0){
        id = (id-1)/2;
        segtree[id] = max(segtree[id*2+1],segtree[id*2+2]);
    }
}
int query(int ql,int qr,int l,int r,int pos){
    if(ql >= r || qr <= l) return NINF;
    if(ql <= l && qr >= r) return segtree[pos]; 
    int mid = (l+r)/2;
    return max(query(ql,qr,l,mid,pos*2+1), query(ql,qr,mid,r,pos*2+2));
}
int main()
{
    while(scanf("%d%d",&n,&m) != EOF){
        k = 1;
        while(k < n) k*=2;
        memset(grade,0xc0,sizeof(grade));      //将所有成绩初始化为负无穷,当n为奇数时,树的空余位置自动为负无穷。
                                                // segtree不用初始化。 一开始超时在数组的初始化上。
        for(int i=0;i


你可能感兴趣的:(segment,tree)