HDU1754 线段树模板题

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754

题目分析:对于给出的一个很长的区间,对其进行单点更新值和区间求最大值的操作,由于查询的区间很大,且查询次数多,这里用线段树求解将是十分合适的

注意点:1.对于存放线段树的数组大小需要开大一些

    2.对于c语言的字符输入%c之前需要加一个空格保证输入准确

 1 #include<iostream>
 2 #include<string.h>
 3 using namespace std;
 4
 5 const int N = 200005;
 6 int grade[N];
 7 int tree[N<<2];                    //这里建立的树的数组大小需要是N的4倍 否则不够用
 8 int n, m;
 9
10 int max(int a, int b){
11     if(a > b) return a;
12     else return b;
13 }
14
15 void build_tree(int start, int end, int node){                    //线段树的建立
16     if(start == end){
17         tree[node] = grade[start];
18     }else{
19         int mid = (start + end) / 2;
20         int left_node = node*2;
21         int right_node = node*2+1;
22
23         build_tree(start, mid, left_node);
24         build_tree(mid+1, end, right_node);
25         tree[node] = max(tree[left_node], tree[right_node]);
26     }
27 }
28
29 void update_tree(int start, int end, int node, int index, int value){    //单点更新值
30     if(start == end){
31         tree[node] = value;
32     }else{
33         int mid = (start + end) / 2;
34         int left_node = node*2;
35         int right_node = node*2+1;
36
37         if(index <= mid)
38             update_tree(start, mid, left_node, index, value);
39         else
40             update_tree(mid+1, end, right_node, index, value);
41         tree[node] = max(tree[left_node], tree[right_node]);
42     }
43 }
44
45 int search_tree(int start, int end, int node, int l, int r){        //区间查询最大值
46     if(l > end || r < start){
47         return 0;
48     }else if(l <= start && r >= end){
49         return tree[node];
50     }else if(start == end){      //这里的个递归出口放在后面是有原因的,有可能存在start==end 但是l和r根本和start end没有交集的情况,所以先判去了后者
51         return tree[node];
52     }
53     int mid = (start + end) / 2;
54     int left_node = node*2;
55     int right_node = node*2+1;
56
57     int left_max = search_tree(start, mid, left_node, l, r);
58     int right_max = search_tree(mid+1, end, right_node, l, r);
59     int ans = max(left_max, right_max);
60     return ans;
61 }
62
63 int main(){
64     while(scanf("%d%d", &n, &m) != EOF){
65         for(int i = 1; i <= n; i++)
66             scanf("%d", &grade[i]);
67         build_tree(1, n, 1);
68         for(int i = 1; i <= m; i++){
69             char c;
70             int a, b;
71             scanf(" %c %d %d", &c, &a, &b);            //对于c语言的输入字符在%c之前需要一个空格,否则c就读取不到需要的字符了
72             if(c == ‘U‘) update_tree(1, n, 1, a, b);
73             else{
74                 int ans = search_tree(1, n, 1, a, b);
75                 printf("%d\n", ans);
76             }
77         }
78     }
79     return 0;
80 }

原文地址:https://www.cnblogs.com/findview/p/11811802.html

时间: 2024-10-24 10:32:16

HDU1754 线段树模板题的相关文章

[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

LA 2191电位计(线段树模板题)

线段树模板题,没啥好说的.....注意输出是case之间空一行就行.........之前一直没注意,一直wa 代码如下: #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #includ

1270. 数列区间最大值(climits用法+线段树模板题)

题目链接: https://www.acwing.com/problem/content/1272/ 题解: 线段树模板题,单点求和.区间查询都可 AC代码: #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <climits> using namespace std; const int N = 1e5+10; int a

P1243~P1247 线段树模板题总结

前言 这几天刚刚刷了5道线段树(水)题,现在来总结一下. 首先是犯的不少错误: 1.建树.更新函数没有return.这是最气的,每次最后程序错误查了半天也没查出来,最后发现是没有return.递归边界要return,递归边界要return,递归边界要return,重要的事情说三遍. 2.判断查找区间于线段的变量写反.听说这个是常犯错误. 然后说一下学线段树的收获.线段树的代码量的确多,很能练自己的思维,而且学的过程中简单的理解了一下#define的用处.线段树用来解决区间查询,区间修改都很方便,

HDU 1166 线段树模板题

坐了3天的火车,终于到外婆家了(┬_┬).这次北京之旅颇有感触,虽然学到的东西不是很多(主要是自己的原因,没有认真学,并不是老师讲的不好),不过出去见见世面也是好的.最后一场比赛印象颇深,被虐的有点惨....记得当时有道题感觉自己能过,想用数组模拟链表水过,可是无论怎么优化一直超时@[email protected]后面比完后听朋友说那题应该用线段树做,顿时恍然大悟,然并卵,线段树的模板早忘了.....今天做道线段树的模板题先复习一下,过会再想想那道题. 敌兵布阵 Time Limit: 200

poj2823 线段树模板题 点修改(也可以用单调队列)

这道题吧 没计算时间 因为给了那么多 一算还可以 就直接写了线段树,刘汝佳那本模板 然后!poj的g++比C++慢大约500ms.......g++tle,C++就过了 Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 67576   Accepted: 19163 Case Time Limit: 5000MS Description An array of size n ≤ 106 is

权值线段树模板题

array Time Limit: 1500ms Memory Limit: 256M Description You are given an array . Initially, each element of the array is unique.Moreover, there are  instructions. Each instruction is in one of the following two formats: 1. ,indicating to change the v

[bzoj1568]李超线段树模板题(标志永久化)

题意:要求在平面直角坐标系下维护两个操作: 1.在平面上加入一条线段.记第i条被插入的线段的标号为i. 2.给定一个数k,询问与直线 x = k相交的线段中,交点最靠上的线段的编号. 解题关键:注意标志的作用 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cmath> 6 #include<iostrea

又长又臭又慢的线段树 模板题hdu1698 Just a Hook

Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 30901    Accepted Submission(s): 15221Problem Description In the game of DotA, Pudge's meat hook is actually the most horrible thing f