hud 1754 I Hate It 线段树 点修改

来源:互联网 发布:淘宝只能开一个店铺 编辑:程序博客网 时间:2024/04/29 18:17

I Hate It

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


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 61 2 3 4 5Q 1 5U 3 6Q 3 4Q 4 5U 2 9Q 1 5
 


 

Sample Output
5659

 

 

 

#include <map>#include <set>#include <stack>#include <queue>#include <cmath>#include <vector>#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;#define INF 0x3f3f3f3f#define inf -0x3f3f3f3f#define FOR(a,b) for(int i =  a ; i < b ; i++)#define mem0(a) memset(a,0,sizeof(a))#define mem1(a) memset(a,-1,sizeof(a))#define FOPENIN(IN) freopen(IN, "r", stdin)#define FOPENOUT(OUT) freopen(OUT, "w", stdout)const int NUM = 200000+10;int a[NUM<<2];//NUM=NUM*2^2void pushUp(int cur){//更新a值    a[cur] = max(a[cur<<1],a[cur<<1|1]);//x<<1|1等价于x*2+1}//左右子结点编号分别为2i和2i+1void build(int l,int r,int cur){//建立线段树    if(l == r) {        scanf("%d",&a[cur]);return ;    }    int mid = (l+r)>>1;//求l到r的中间点=(l+(r-l)/2)    build(l,mid,cur<<1);//左子树,2*cur    build(mid+1,r,cur<<1|1);//右子树,2*cur+1    pushUp(cur); //更新结点}void update(int p ,int v,int l,int r,int cur){    if(l == r){        a[cur] = v;//叶结点,直接更新a    }    else {    int mid = (r + l )>>1 ;          if(p <= mid ){//递归更新左子树和右子树            update(p,v,l,mid,cur<<1);        }        else {            update(p,v,mid+1,r,cur<<1|1);        }        pushUp(cur);//计算本结点的a    }}int query(int ql,int qr,int l,int r,int cur){    int mid = (l + r )>>1 ;    int ans = inf;    if(ql <= l&& r <= qr)return a[cur];//当前结点完全包含在查询区域内    if(ql <= mid){ //往左走        ans=max(ans,query(ql,qr,l,mid,cur<<1));    }    if(mid < qr){//往右走        ans=max(ans,query(ql,qr,mid+1,r,cur<<1|1));    }    return ans ;}int main(){    int N,M;//分别代表学生数目和操作数目    while(scanf("%d%d",&N,&M)!=EOF){        build(1,N,1);        while(M--){            char s[2];            int A,B;            scanf("%s",s);            if(s[0]=='Q'){                scanf("%d%d",&A,&B);                printf("%d\n",query(A,B,1,N,1));            }            else if(s[0]=='U'){                scanf("%d%d",&A,&B);                update(A,B,1,N,1);            }        }    }    return 0;}


 

0 0
原创粉丝点击