[问题描述]
很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。
这让很多学生很反感。
    不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
[输入]
本题目包含多组测试,请处理到文件结束。
在每个测试的第一行,有两个正整数 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。
[输出]
对于每一次询问操作,在一行里面输出最高成绩。
[输入样例]
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

[输出样例]
5 6 5 9

提供原程序和具体分析如下:

提供原程序前,先进行如下几点说明(源程序的风格):

•maxn是题目给的最大区间,而节点数要开4倍,确切的来说节点数要开大于maxn的最小2x的两倍
•lson和rson分辨表示结点的左儿子和右儿子,由于每次传参数的时候都固定是这几个变量,所以可以用预定于比较方便的表示
•以前的写法是另外开两个个数组记录每个结点所表示的区间,其实这个区间不必保存,一边算一边传下去就行,只需要写函数的时候多两个参数,结合lson和rson的预定义可以很方便
•PushUP(int rt)是把当前结点的信息更新到父结点
•PushDown(int rt)是把当前结点的信息更新给儿子结点
•rt表示当前子树的根(root),也就是当前所在的结点

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4
 5 #define lson l , m , rt << 1       //用lson来代替三个参数:l,m,rt*2,注意rt<<1就是rt*2;
 6 #define rson m + 1 , r , rt << 1 | 1    //同上,rt<<1|1,相当于rt*2+1;
 7 const int maxn =222222;
 8 int MAX[maxn<<2];                       //二进行向右移两位相当于maxn*4;
 9 void PushUP(int rt){                       //用于向上回溯
10     MAX[rt]= max(MAX[rt<<1] , MAX[rt<<1|1]);     //选择左右孩子中的较大者
11 }
12 void build(int l,int r,int rt){                //建立线段树
13     if(l == r){
14         scanf("%d",&MAX[rt]);                  //至叶结点时读数
15         return;
16     }
17     int m =(l + r)>>1;
18     build(lson);                               //线段树分为左孩子
19     build(rson);                               //线段树分为右孩子
20     PushUP(rt);                                //向上回溯
21 }
22 void update(int p,int sc,int l,int r,int rt){
23     if(l == r){
24         MAX[rt]= sc;
25         return;
26     }
27     int m =(l + r)>>1;
28     if(p <= m) update(p , sc , lson);
29     else update(p , sc , rson);
30     PushUP(rt);
31 }
32 int query(int L,int R,int l,int r,int rt){
33     if(L <= l && r <= R){
34         return MAX[rt];
35     }
36     int m =(l + r)>>1;
37     int ret =0;
38     if(L <= m) ret = max(ret , query(L , R , lson));
39     if(R > m) ret = max(ret , query(L , R , rson));
40     return ret;
41 }
42 int main(){
43     int n , m;
44     while(~scanf("%d%d",&n,&m)){
45         build(1 , n , 1);
46         while(m --){
47             char op[2];
48             int a , b;
49             scanf("%s%d%d",op,&a,&b);
50             if(op[0]=='Q')printf("%d\n",query(a , b , 1 , n , 1));
51             else update(a , b , 1 , n , 1);
52         }
53     }
54     return 0;
55 }

转载于:https://www.cnblogs.com/jjzzx/p/5252649.html

线段树——I hate it相关推荐

  1. 二逼平衡树——树套树(线段树套Splay平衡树)

    题面 Bzoj3196 解析 线段树和Splay两棵树套在一起,常数直逼inf,但最终侥幸过了 思路还是比较简单, 在原数组维护一个下标线段树,再在每一个线段树节点,维护一个对应区间的权值Splay. ...

  2. 线段树——HDU - 1698

    题目含义 就是初始化一堆数为1 可以经过操作把一个区间的数都改变 并求这堆数的总大小 题目分析 有一个 #include<iostream> #include<stdio.h> ...

  3. BZOJ.1558.[JSOI2009]等差数列(线段树 差分)

    BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...

  4. 【线段树分治 线性基】luoguP3733 [HAOI2017]八纵八横

    不知道为什么bzoj没有HAOI2017 题目描述 Anihc国有n个城市,这n个城市从1~n编号,1号城市为首都.城市间初始时有m条高速公路,每条高速公路都有一个非负整数的经济影响因子,每条高速公路 ...

  5. [bzoj1582][Usaco2009 Hol]Holiday Painting 节日画画_线段树

    Holiday Painting 节日画画 bzoj-1582 Usaco-2009 Hol 题目大意:给定两个n*m的01网格图.q次操作,每次将第二个网格图的子矩阵全部变成0或1,问每一次操作后两 ...

  6. codefores 786B. Legacy(最短路,线段树优化拆点,好题)

    题目链接 B. Legacy time limit per test2 seconds memory limit per test256 megabytes inputstandard input o ...

  7. 【题解】BZOJ 3065: 带插入区间K小值——替罪羊树套线段树

    题目传送门 题解 orz vfk的题解 3065: 带插入区间K小值 系列题解 一 二 三 四 惨 一开始用了一种空间常数很大的方法,每次重构的时候merge两颗线段树,然后无限RE(其实是MLE). ...

  8. 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)

    题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...

  9. bzoj1095: [ZJOI2007]Hide 捉迷藏 线段树维护括号序列 点分治 链分治

    这题真是十分难写啊 不管是点分治还是括号序列都有一堆细节.. 点分治:时空复杂度$O(n\log^2n)$,常数巨大 主要就是3个堆的初始状态 C堆:每个节点一个,为子树中的点到它父亲的距离的堆. B ...

  10. POJ 2528 Mayor's posters(线段树)

    题目大意 贴海报.每张海报的高度都是一样的,唯独宽度不一样.每张海报只能占用整数倍的单位线段长度,贴了 n(n<=10000) 张海报之后,有几张能够看见(有一个角能看见这张海报也算被看见了)? ...

最新文章

  1. INDEX FULL SCAN和INDEX FAST FULL SCAN区别
  2. stm32 中bootloader、startup_stm32f10x_md.s的作用
  3. spring的aop配置-配置将通知织入目标对象
  4. python编写程序输入整数n求n_Python入门习题----N=ABXBA
  5. SVN客户端与服务端安装详解
  6. CYYMysql 源码解读 2
  7. 机器学习中的概率模型和概率密度估计方法及VAE生成式模型详解之二(作者简介)...
  8. 基础学习:高斯混合模型GMM
  9. ubuntu下安装anjuta
  10. golang接口与反射剖析
  11. Python里面这些点,据说80%的新手都会一脸懵逼,不信就往下看......
  12. 在python中读取.pgm格式图像
  13. 联想Y470 非虚拟机安装苹果Mac OS X Mavericks 10.9.1教程详解(文字+图片),通俗易懂亲自动手——序列三之安装过程,设置选项
  14. 人一生要看的60本书
  15. 终结版水与油——致我献给魔术的青春
  16. 手机java大作_恐怖大作-暗黑惊怵
  17. 集合长度可变的实现原理(解析为什么集合长度可变)
  18. 华为手机居然还能这样提高续航?简单设置一下,一天一充很轻松
  19. ffmpeg 实现 视频与gif互转
  20. 磁性微型机器人通过结肠翻筋斗以输送药物

热门文章

  1. Python,入门1
  2. Windows 2003域更名工具(Domain Rename Tool)
  3. 阿里巴巴Java开发 之 MySQL规约
  4. priority_queue用法
  5. VS2010 在Win 7 附加w3wp.exe进程进行调试
  6. 使用iBatis和ObjectDataSource轻松实现分页
  7. Stanford NLP - 命名实体识别 - NERClassifierCombiner
  8. 线性排序算法-堆排序 (2)
  9. 项目微管理23 - 会议
  10. 几种实用的pythonic语法