线段树模板hdu 1754:I Hate It

      I Hate It

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

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

Recommend

lcy  &nbsp|  &nbspWe have carefully selected several similar problems for you:  1698 1542 1394 2795 1540

分析:此题为经典线段树模板题, 标志性的更新和查询操作, 如果无数条更新和查询操作时, 想到线段树, 很可能就是一道与此题类似的线段树题欧。。

ac代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 using namespace std;
 5
 6 const int N=200000+50;
 7 struct tree{
 8     int l, r, maxn;
 9 };
10 tree t[N*3];
11 int ans;
12
13 void build(int m, int l, int r)
14 {
15     t[m].l = l;
16     t[m].r = r;
17     if(l==r)
18     {
19         scanf("%d", &t[m].maxn);
20         return;
21     }
22     int mid = (l + r) >> 1;
23     build(m<<1, l, mid);
24     build(m<<1|1, mid+1, r);
25     t[m].maxn = max(t[m<<1].maxn, t[m<<1|1].maxn);
26 }
27 void U(int m, int a, int b)
28 {
29     if(t[m].l == t[m].r && t[m].l == a)
30     {
31         t[m].maxn = b;
32         return;
33     }
34     int mid = (t[m].l + t[m].r) >> 1;
35     if(a <= mid)
36         U(m<<1, a, b);
37     else
38         U(m<<1|1, a, b);
39     t[m].maxn = max(t[m<<1].maxn, t[m<<1|1].maxn);
40 }
41 void Q(int m, int l, int r)
42 {
43     if(t[m].l == l && t[m].r == r)
44     {
45         ans = max(ans, t[m].maxn);
46         return;
47     }
48     int mid = (t[m].l + t[m].r) >> 1;
49     if(r <= mid)
50         Q(m<<1, l, r);
51     else if(l >= mid + 1)
52         Q(m<<1|1, l, r);
53     else
54     {
55         Q(m<<1, l, mid);
56         Q(m<<1|1, mid+1, r);
57     }
58 }
59 int main()
60 {
61     int n, m;
62     while(scanf("%d%d", &n, &m)!=EOF)
63     {
64         build(1, 1, n);
65         for(int i=0;i<m;i++)
66         {
67             getchar();
68             char c;
69             int a, b;
70             scanf("%c", &c);
71             scanf("%d%d", &a, &b);
72             if(c == ‘Q‘)
73             {
74                 ans = 0;
75                 Q(1, a, b);
76                 printf("%d\n", ans);
77             }
78             else
79                 U(1, a, b);
80         }
81     }
82     return 0;
83 }

原文地址:https://www.cnblogs.com/sqdtss/p/9437786.html

时间: 2024-10-19 07:19:37

线段树模板hdu 1754:I Hate It的相关文章

【线段树】hdu 1754 I Hate It

[线段树]hdu 1754 I Hate It 题目链接:hdu 1754 I Hate It 题目大意 N个学生的初始成绩已知,操作m次,每次要么将第i个学生的成绩更新,要么查找区间[x,y]的最大成绩. 很显然这是一道线段树,点修改.区间查询,笔者第三道线段树,完全自己敲的,直接AC~(≧▽≦)/~啦啦啦. 如果单纯查找区间最大值,时间复杂度O(N),而线段树O(logN),当查询的次数非常多时,显然后者更高效! 说一下思路 线段树的点修改[点更新]:直接将叶节点更新为输入的数据,对照"敌兵

裸裸的线段树(hdu 1754)

线段树的第一发. 哪天忘了还能够让自己找找回顾. 线段树操作: build  : 建树. update:点改动: query:查询 Input 在每一个測试的第一行,有两个正整数 N 和 M ( 0<N<=200000,0<M<5000 ),分别代表学生的数目和操作的数目. 学生ID编号分别从1编到N. 第二行包括N个整数,代表这N个学生的初始成绩,当中第i个数代表ID为i的学生的成绩. 接下来有M行.每一行有一个字符 C (仅仅取'Q'或'U') .和两个正整数A.B. 当C为'

hdu 4819 二维线段树模板

/* HDU 4819 Mosaic 题意:查询某个矩形内的最大最小值, 修改矩形内某点的值为该矩形(Mi+MA)/2; 二维线段树模板: 区间最值,单点更新. */ #include<bits/stdc++.h> using namespace std; const int INF = 0x3f3f3f3f; const int MAXN = 1010; int N, Q; struct Nodey { int l, r; int Max, Min; }; int locx[MAXN], l

【HDU 4819】Mosaic 二维线段树模板

二维线段树的模板题,和一维一样的思路,更新的时候注意一下细节. 存模板: /* 二维线段树模板整理 */ #include<cstdio> #include<algorithm> using namespace std; #define lson (pos<<1) #define rson (pos<<1|1) const int maxn = 805; const int INF = (1 << 30); int n; int posX[max

线段树模板(结构体)

线段树研究了两天了,总算有了点眉目,今天也把落下的题,补了一下. 贴一份线段树模板 线段树的特点: 1. 每一层都是区间[a, b]的一个划分,记 L = b - a 2. 一共有log2L层 3. 给定一个点p,从根到叶子p上的所有区间都包含点p,且其他区间都不包含点p. 4. 给定一个区间[l; r],可以把它分解为不超过2log2 L条不相交线段的并. 总结来说:线段树最近本的应用是4点: 1.单点更新:单点替换.单点增减 2.单点询问 3.区间询问:区间之和.区间最值 4.区间更新:区间

【线段树】 HDU 5025 A Corrupt Mayor&#39;s Performance Art

更新区间内颜色 输出区间内的颜色总数 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <string> #include <iostream> #include <algorithm> #include <sstream> #include <math.h> using namespace std; #include <

[ACM] 线段树模板

#include<iostream> #include<cmath> using namespace std; #define maxn 200005 class Node{ public: int l,r; int add;//附加值 int sum; }node[maxn]; int getRight(int n){//获得满足2^x>=n的最小x[从0层开始,给编号获得层数] return ceil(log10(n*1.0)/log10(2.0)); } void bu

[POJ2104] 区间第k大数 [区间第k大数,可持久化线段树模板题]

可持久化线段树模板题. #include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <vector> using namespace std; int n,q,tot,a[110000]; in

【线段树】HDU 3397 Sequence operation 区间合并

操作 Change operations: 0 a b change all characters into '0's in [a , b] 1 a b change all characters into '1's in [a , b] 2 a b change all '0's into '1's and change all '1's into '0's in [a, b] Output operations: 3 a b output the number of '1's in [a,