ACM 粗心永远AC不了系列——HDU 1754 I Hate It|线段树区间求最值
来源:互联网 发布:数据可视化软件下载 编辑:程序博客网 时间:2024/06/05 10:57
线段树应用水题之一
一:线段树基本概念
1:概述
线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结构的特性,它基本能保持每个操作的复杂度为O(lgN)!
性质:父亲的区间是[a,b],(c=(a+b)/2)左儿子的区间是[a,c],右儿子的区间是[c+1,b],线段树需要的空间为数组大小的四倍
2:基本操作(demo用的是查询区间最小值)
线段树的主要操作有:
(1):线段树的构造 void build(int node, int begin, int end);
(2):区间查询int query(int node, int begin, int end, int left, int right);
(3):区间或节点的更新 及 线段树的动态维护update (这是线段树核心价值所在,节点中的标记域可以解决N多种问题)
动态维护需要用到标记域,延迟标记等。
3:主要应用
(1):区间最值查询问题 (见模板1)
(2):连续区间修改或者单节点更新的动态查询问题 (见模板2)
(3):多维空间的动态查询 (见模板3)
具体线段树ACM情况可以参看转载博客:数据结构专题——线段树
题目来源:I Hate It
ac代码:
#pragma warning(disable:4996) #include <stdio.h> #include <algorithm>using namespace std;#define MAXN 200000 + 10int a[MAXN];struct Node{int l = 0, r = 0, v = 0;}tree[800010];//注意数组一定要开大,之前开了400010,结果愣是超时,改了20+次才发现数组开的不够大,粗心void build(int i, int l, int r) {tree[i].l = l;tree[i].r = r;if (l == r){tree[i].v = a[l];return;// 叶子节点退出}int mid = (r + l) >> 1;build(i << 1, l, mid);// 建立左子树 数组完全二叉树 i*2==i<<1build(i << 1 | 1, mid + 1, r);// 建立右子树 数组完全二叉树 i*2+1==i<<1|1tree[i].v = max(tree[i << 1].v, tree[i << 1 | 1].v);}void update(int num, int x, int v) {if (tree[num].l == x && tree[num].r == x) {tree[num].v = v;return;}int mid = (tree[num].l + tree[num].r) >> 1;if (x > mid)update(num << 1 | 1, x, v);elseupdate(num << 1, x, v);tree[num].v = max(tree[num << 1].v, tree[num << 1 | 1].v);}int query(int i, int left, int right) {if (tree[i].l == left && tree[i].r == right) {return tree[i].v;}int mid = (tree[i].l + tree[i].r) >> 1;if (right <= mid)return query(i << 1, left, right);else if (left >= mid + 1)return query(i << 1 | 1, left, right);else {int le = query(i << 1, left, mid);int ri = query(i << 1 | 1, mid + 1, right);return max(le, ri);}}int main(){int n, m;char s[5];while (~scanf("%d%d", &n, &m)){for (int i = 1; i <= n; ++i){scanf("%d", a + i);}build(1, 1, n);for (int i = 0; i < m; ++i){scanf("%s", s);int a, b;scanf("%d%d", &a, &b);if (s[0] == 'Q')printf("%d\n", query(1, a, b));else if (s[0] == 'U')update(1, a, b);}}return 0;}
0 0
- ACM 粗心永远AC不了系列——HDU 1754 I Hate It|线段树区间求最值
- ACM 粗心永远AC不了系列——UVA 512
- ACM 粗心永远AC不了系列——HDU 1097 A hard puzzle
- HDU 1754 I Hate It(线段树区间求最值)
- HDU 1754 I Hate It(线段树区间求最值)
- ACM 粗心永远AC不了系列——小Hi的烦恼|“五维数点”问题
- 线段树(区间最大值查询和点修改)——I Hate It ( HDU 1754 )
- HDU 1754 I Hate It 线段树区间求最大
- HDU 1754 I Hate It(线段树,区间最大值)
- HDU 1754 I Hate It(线段树求区间最大值)
- B - I Hate It HDU 1754 (线段树+区间)
- hdu 1754 I Hate It 线段树-区间最值
- HDU-1754I Hate It 线段树区间最值
- 【HDU-1754】-I Hate It(线段树,区间最大值)
- HDU-1754 I Hate It(线段树,区间最大值)
- hdu-1754 I Hate It【线段树求区间最大值】
- 线段树系列-hdu-1754-I Hate It-单点修改求区间最值
- ACM 粗心永远AC不了系列——UVa 213 Message Decoding(World Finals1991,字符串) |二维数组的妙用
- RESTful API 设计指南(转)
- 链表13:链表的k逆序
- CentOS7下LAMP环境的搭建
- 逆波兰表达式
- Android 读取联系人
- ACM 粗心永远AC不了系列——HDU 1754 I Hate It|线段树区间求最值
- Unity脚本-移动相关知识总结
- Android6.0运行时权限(一)
- Eclipse常用的快捷键
- 谷歌正打造超速AI,能像人类一样快速学习
- 业务建模:枚举字段的类型选择
- 安装libevent遇到的问题,error while loading shared libraries: libevent-2.0.so.5,
- javascript 中数组常用方法总结
- LeetCode刷题(C++)——Binary Tree Zigzag Level Order Traversal(Medium)