HDU1754 && HDU1166 线段树模板题
HDU1754
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754
题目分析:对于给出的一个很长的区间,对其进行单点更新值和区间求最大值的操作,由于查询的区间很大,且查询次数多,这里用线段树求解将是十分合适的
注意点:1.对于存放线段树的数组大小需要开大一些
2.对于c语言的字符输入%c之前需要加一个空格保证输入准确
#include<iostream>
#include<string.h>
using namespace std; const int N = ;
int grade[N];
int tree[N<<]; //这里建立的树的数组大小需要是N的4倍 否则不够用
int n, m; int max(int a, int b){
if(a > b) return a;
else return b;
} void build_tree(int start, int end, int node){ //线段树的建立
if(start == end){
tree[node] = grade[start];
}else{
int mid = (start + end) / ;
int left_node = node*;
int right_node = node*+; build_tree(start, mid, left_node);
build_tree(mid+, end, right_node);
tree[node] = max(tree[left_node], tree[right_node]);
}
} void update_tree(int start, int end, int node, int index, int value){ //单点更新值
if(start == end){
tree[node] = value;
}else{
int mid = (start + end) / ;
int left_node = node*;
int right_node = node*+; if(index <= mid)
update_tree(start, mid, left_node, index, value);
else
update_tree(mid+, end, right_node, index, value);
tree[node] = max(tree[left_node], tree[right_node]);
}
} int search_tree(int start, int end, int node, int l, int r){ //区间查询最大值
if(l > end || r < start){
return ;
}else if(l <= start && r >= end){
return tree[node];
}else if(start == end){ //这里的个递归出口放在后面是有原因的,有可能存在start==end 但是l和r根本和start end没有交集的情况,所以先判去了后者
return tree[node];
}
int mid = (start + end) / ;
int left_node = node*;
int right_node = node*+; int left_max = search_tree(start, mid, left_node, l, r);
int right_max = search_tree(mid+, end, right_node, l, r);
int ans = max(left_max, right_max);
return ans;
} int main(){
while(scanf("%d%d", &n, &m) != EOF){
for(int i = ; i <= n; i++)
scanf("%d", &grade[i]);
build_tree(, n, );
for(int i = ; i <= m; i++){
char c;
int a, b;
scanf(" %c %d %d", &c, &a, &b); //对于c语言的输入字符在%c之前需要一个空格,否则c就读取不到需要的字符了
if(c == 'U') update_tree(, n, , a, b);
else{
int ans = search_tree(, n, , a, b);
printf("%d\n", ans);
}
}
}
return ;
}
HDU1166
题目分析:
也是一题线段树的模板题,单点更新和区间查询求和(本质上和区间求最大值是一样的)
代码:
#include<iostream>
#include<string>
#include<string.h>
using namespace std; const int N = ;
int peo[N];
int tree[N<<]; void build_tree(int start, int end, int node){
if(start == end){
tree[node] = peo[start];
}else{
int mid = (start + end) / ;
int left_node = node*;
int right_node = node*+; build_tree(start, mid, left_node);
build_tree(mid+, end, right_node);
tree[node] = tree[left_node] + tree[right_node];
}
} void update_tree(int start, int end, int node, int index, int value){
if(start == end){
tree[node] += value;
}else{
int mid = (start + end) / ;
int left_node = node*;
int right_node = node*+; if(index <= mid)
update_tree(start, mid, left_node, index, value);
else
update_tree(mid+, end, right_node, index, value);
tree[node] = tree[left_node] + tree[right_node];
}
} int query_tree(int start, int end, int node, int l, int r){
if(end < l || start > r){
return ;
}else if(start >= l && end <= r){
return tree[node];
}else if(start == end){
return tree[node];
}
int mid = (start + end) / ;
int left_node = node*;
int right_node = node*+; int left_sum = query_tree(start, mid, left_node, l, r);
int right_sum = query_tree(mid+, end, right_node, l, r);
int ans = left_sum + right_sum;
return ans;
} int main(){
int t;
scanf("%d", &t);
int cnt = ;
while(t--){
printf("Case %d:\n", cnt++);
int n;
scanf("%d", &n);
for(int i = ; i <= n; i++)
scanf("%d", &peo[i]);
build_tree(, n, );
string s;
int a, b;
while(cin>>s){
if(s == "End") break;
scanf("%d%d", &a, &b);
if(s == "Query"){
int ans = query_tree(, n, , a, b);
printf("%d\n", ans);
}
if(s == "Add"){
update_tree(, n, , a, b);
}
if(s == "Sub"){
update_tree(, n, , a, -b);
}
}
}
return ;
}
HDU1754 && HDU1166 线段树模板题的更多相关文章
- [AHOI 2009] 维护序列(线段树模板题)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...
- hdu1823(二维线段树模板题)
hdu1823 题意 单点更新,求二维区间最值. 分析 二维线段树模板题. 二维线段树实际上就是树套树,即每个结点都要再建一颗线段树,维护对应的信息. 一般一维线段树是切割某一可变区间直到满足所要查询 ...
- [POJ2104] 区间第k大数 [区间第k大数,可持久化线段树模板题]
可持久化线段树模板题. #include <iostream> #include <algorithm> #include <cstdio> #include &l ...
- HDU 1698 Just a Hook (线段树模板题-区间求和)
Just a Hook In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of t ...
- UESTC - 1057 秋实大哥与花 线段树模板题
http://acm.uestc.edu.cn/#/problem/show/1057 题意:给你n个数,q次操作,每次在l,r上加上x并输出此区间的sum 题解:线段树模板, #define _CR ...
- POJ - 3264 线段树模板题 询问区间最大最小值
这是线段树的一个模板题,给出一串数字,然后询问区间的最大最小值. 这个其实很好办,只需把线段树的节点给出两个权值,一个是区间的最小值,一个是区间的最大值,初始化为负无穷和正无穷,然后通过不断地输入节点 ...
- 敌兵布阵 HDU - 1166 (树状数组模板题,线段树模板题)
思路:就是树状数组的模板题,利用的就是单点更新和区间求和是树状数组的强项时间复杂度为m*log(n) 没想到自己以前把这道题当线段树的单点更新刷了. 树状数组: #include<iostrea ...
- zkw线段树模板题
学了zkw线段树,觉得没什么必要刷专题的吧(切不动啊).. 那先放一个模板题吧(我绝不会和你说搬了一道树状数组模板题的!!!) 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某一个数加 ...
- P1243~P1247 线段树模板题总结
前言 这几天刚刚刷了5道线段树(水)题,现在来总结一下. 首先是犯的不少错误: 1.建树.更新函数没有return.这是最气的,每次最后程序错误查了半天也没查出来,最后发现是没有return.递归边界 ...
随机推荐
- 洛谷 P1156 垃圾陷阱 题解
题目传送门 dp+排序+01背包 就完事了??? 貌似就是这样的 代码: //dp 排序 01背包 #include<iostream> #include<cstdio> #i ...
- treegrid 表格树
treegrid 实现表格树的结构 效果图: 第一步:页面布局 <div class="col-sm-12 select-table table-striped" styl ...
- Jenkins的简介及安装
Jenkins介绍 Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能. 1. jenkins就是 ...
- SPOJ31428 FIBONOMIAL(斐波那契数列)
神鱼推题,必是好题. 前几天刚做过[BJOI2019]勘破神机,于是就会这题了.(BJ人民强啊……%鱼) 首先要求是 $$\sum\limits_{i=0}^nx^if_i$$ 应该很明显能想到把 $ ...
- [LeetCode] 322. Coin Change 硬币找零
You are given coins of different denominations and a total amount of money amount. Write a function ...
- 一步步从零开始用 webpack 搭建一个大型项目
开篇 很多人都或多或少使用过 webpack,但是很少有人能够系统的学习 webpack 配置,遇到错误的时候就会一脸懵,不知道从哪查起?性能优化时也不知道能做什么,网上的优化教程是不是符合自己的项目 ...
- 检查hdfs块的块-fsck
hadoop集群运行过程中,上下节点是常有的事情,如果下架节点,hdfs存储的块肯定会受到影响. 如何查看当前的hdfs的块的状态 hadoop1.x时候的命令,hadoop2.x也可使用: hado ...
- 4 datax mysql 和hbase的 相互导入
mysql-->hbase 0 参考文档: https://github.com/alibab ...
- 2 datax mysql 和 mysql之间相互导入
插件文档: https://github.com/alibaba/DataX/blob/master/hdfswriter/doc/hdfswriter.md 1,参照第1篇日记,安装好datax ...
- mongodb集群化
转自:https://www.cnblogs.com/nulige/p/7613721.html 一.mongodb主从复制配置 主从复制是MongoDB最常用的复制方式,也是一个简单的数据库同步备份 ...