hdu1754 I hate it线段树模板 区间最值查询
题目链接:这道题是线段树,树状数组最基础的问题
两种分类方式:按照更新对象和查询对象
单点更新,区间查询;
区间更新,单点查询;
按照整体维护的对象:
维护前缀和;
维护区间最值.
线段树模板代码
#include<iostream> #include<string.h> #include<stdio.h> #include<math.h> #include<algorithm> using namespace std; #define re(i,n) for(int i=0;i<n;i++) typedef long long ll; * 1e5 + ; #define lson(x) x<<1,f,mid #define rson(x) x<<1|1,mid+1,t int n, m; ]; int x, y; int ans; void build(int r, int f, int t){ if (f == t){ scanf("%d", &tr[r]); return; } ; build(lson(r)),build(rson(r)); tr[r] = max(tr[r << ], tr[r << | ]); } void query(int r, int f, int t){ if (f >= x&&t <= y){ ans = max(ans, tr[r]); return; } ; if (x <= mid)query(lson(r)); if (y > mid)query(rson(r)); } void update(int r, int f, int t){ if (f == t){ tr[r] = y; return; } ; if (x<= mid)update(lson(r)); else update(rson(r)); tr[r] = max(tr[r << ], tr[r << | ]); } int main(){ //freopen("in.txt", "r", stdin); while (cin >> n >> m){ build(, , n); while (m--){ ]; scanf("%s%d%d", op,&x,&y); ] == 'Q'){ if (x > y)swap(x, y); ans = -; query(, , n); printf("%d\n", ans); } else{ update(, , n); } } } ; }
树状数组区间最值模板代码
#include<iostream> #include<stdio.h> #include<algorithm> using namespace std; *1e5+; typedef long long ll; #define re(i,n) for(int i=0;i<n;i++) int a[maxn], c[maxn]; /* a里面存放本值,c里面维护最值 */ int n, q; int lowbit(int x){ return x&-x; } void redo(int i){ c[i] = i; ; j < lowbit(i); j <<= ) if (a[c[i - j]]>a[c[i]])c[i] = c[i - j]; } void init(){ ; i <= n; i++){ redo(i); } } void update(int x, int y){ bool big = y > a[x]; a[x] = y; int i = x; if (big){ /* 这个地方如果错写成a[c[i]]<y就会导致无法传递上去,因为一开始时就是a[c[i]]==y. */ while (i<=n&&a[c[i]] <= y)c[i] = x, i += lowbit(i); } else{ while (i<=n&&c[i] == x)redo(i), i += lowbit(i); } } int query(int l, int r){ int ans = a[r]; while (l<=r){ while (r - lowbit(r) >= l){ ans = max(a[c[r]], ans); r -= lowbit(r); } ans = max(a[r], ans);//根节点 r--;//向下走一步 } return ans; } int main(){ freopen("in.txt", "r", stdin); ){ re(i, n)scanf(]); init(); ; while (q--){ ]; int x, y; qi++; scanf("%s%d%d", &op, &x, &y); ] == 'U'){ update(x, y); } else{ int ans = query(x, y); printf("%d\n", ans); } } } ; }
复杂度是O(lgn*lgn).这道题数据好像有点弱,因为错误的代码也能过这道题.
zwk线段树模板
zwk线段树巧妙之处在于开区间写法,对于长度为N的线段,初始化时,共N+2片叶子:1和N+2空着,2~N+1才是本体,是实实在在的数据.张昆玮说了:如果有1023个数据,那就要有2048片叶子.空间要开到(N+2)*4才行.虽然费了点空间,但编程简洁了.
根节点(1号结点)和每层的第一个节点和最后一个节点是哨兵节点,永远都不会访问到它们.它们的存在只是方便编程.老子曰:将欲取之,必先予之.一言以蔽之,就是两端边界处的节点都是哨兵节点,这是开区间方便编程导致的.
那么闭区间写法行不行呢?对于长度为N的线段,1~N全部用上,查询时闭区间可以转换成开区间.如果有1023个数,那就只需要开辟1024片叶子的树状数组.开区间=闭区间-两个端点.若无论如何都更新两个端点,那就会导致更新的东西有点靠下,这对于结果并没什么影响.需要注意l==r的情形.
zwk开区间写法
#include<iostream> #include<stdio.h> #include<algorithm> using namespace std; * 1e5 + ; typedef long long ll; #define re(i,n) for(int i=0;i<n;i++) ]; int n, q, sz; void update(int x, int v){ x += sz; a[x] = v; ){ x >>= ; a[x] = max(a[x << ], a[x << | ]); } } int query(int l, int r){ l += sz - , r += sz + ; ; ){//当两人不是兄弟时 ){ ans = max(ans, a[l ^ ]); } ){ ans = max(ans, a[r ^ ]); } l >>= , r >>= ; } return ans; } int main(){ //freopen("in.txt", "r", stdin); ){ sz = ; )sz <<= ; re(i, n){ scanf(]); } ); i++)a[i + sz+] = ; ; i>; i--){ a[i] = max(a[i << ], a[i << | ]); } while (q--){ ]; int x, y; scanf("%s%d%d", op, &x, &y); ] == 'U'){ update(x, y); } else{ int ans = query(x, y); printf("%d\n", ans); } } } ; }
zwk闭区间写法:下面的代码有bug.能过题.
#include<iostream> #include<stdio.h> #include<algorithm> using namespace std; * 1e5 + ; typedef long long ll; #define re(i,n) for(int i=0;i<n;i++) ]; int n, q, sz; void update(int x, int v){ x += sz-; a[x] = v; ){ x >>= ; a[x] = max(a[x << ], a[x << | ]); } } int query(int l, int r){ l += sz - , r += sz - ; int ans =max(a[l],a[r]); //查询时先把两个端点给处理掉,就相当于开区间了. /* 这个地方的不同决定了两种写法,我觉得没有必要开区间.闭区间预处理一下就很好. 这个地方如果l==r,就会产生死循环.但是我这么写,这道题却过了.*/ ){//当两人不是兄弟时 ){ ans = max(ans, a[l ^ ]); } ){ ans = max(ans, a[r ^ ]); } l >>= , r >>= ; } return ans; } void init(){ sz = ; ; re(i, n){ scanf("%d", &a[i + sz]);//在1~N之间存放数据 } ); i++)a[i + sz ] = ; ; i>; i--){ a[i] = max(a[i << ], a[i << | ]); } } int main(){ freopen("in.txt", "r", stdin); ){ init(); while (q--){ ]; int x, y; scanf("%s%d%d", op, &x, &y); ] == 'U'){ update(x, y); } else{ int ans = query(x, y); printf("%d\n", ans); } } } ; }
hdu1754 I hate it线段树模板 区间最值查询的更多相关文章
- hdu 1754 I Hate It (线段树求区间最值)
HDU1754 I Hate It Time Limit:3000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u D ...
- xdoj-1324 (区间离散化-线段树求区间最值)
思想 : 1 优化:题意是覆盖点,将区间看成 (l,r)转化为( l-1,r) 覆盖区间 2 核心:dp[i] 覆盖从1到i区间的最小花费 dp[a[i].r]=min (dp[k])+a[i]s; ...
- HDU-1754 I Hate It(线段树,区间最大值)
很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问.当然,老师 ...
- 2016年湖南省第十二届大学生计算机程序设计竞赛---Parenthesis(线段树求区间最值)
原题链接 http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1809 Description Bobo has a balanced parenthes ...
- 滑动窗口(poj,线段树维护区间最值)
题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array i ...
- CodeForces 91B Queue (线段树,区间最值)
http://codeforces.com/problemset/problem/91/B B. Queue time limit per test: 2 seconds memory limit p ...
- POJ 2482 Stars in Your Window (线段树+扫描线+区间最值,思路太妙了)
该题和 黑书 P102 采矿 类似 参考链接:http://blog.csdn.net/shiqi_614/article/details/7819232http://blog.csdn.net/ts ...
- Balanced Lineup:线段树:区间最值 / RMQ
不要被线段树这个名字和其长长的代码吓到. D - Balanced Lineup Description For the daily milking, Farmer John's N cows (1 ...
- HDU6447 YJJ's Salesman-2018CCPC网络赛-线段树求区间最值+离散化+dp
目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog Problem:Portal传送门 原题目描述在最下面. 1e5个点,问 ...
随机推荐
- redis安装及基础操作(1)
============================================================= 编译安装 0.环境 Linux:centos6.5 redis:3.0.5 ...
- django csrf 处理简介
CSRF 是什么 CSRF 即跨站请求伪造,在用户不知情的情况下向有漏洞的网站发送请求.例如有正常网站A,恶意网站B, 用户若对A B 两个网站都有访问,B 可能伪造请求到 A,比如提交表单.至于具体 ...
- Codeforces Round #285 (Div.1 B & Div.2 D) Misha and Permutations Summation --二分+树状数组
题意:给出两个排列,求出每个排列在全排列的排行,相加,模上n!(全排列个数)得出一个数k,求出排行为k的排列. 解法:首先要得出定位方法,即知道某个排列是第几个排列.比如 (0, 1, 2), (0, ...
- JavaSE之概述与基本语法
嘛,这个本来应该发在OOP之前的,无所谓了,补发一下,这篇文章只会对JavaSE的语法做一个基本的概述而已,我会在最近新开一个新坑,也就是JavaEE系列,以后还会有Cpp(相对于C++,我还是更喜欢 ...
- 迄今最深入、最专业的Hololens评测结果,美国AR大咖艾迪·奥夫曼现身说法
http://blackx.baijia.baidu.com/article/530213 在空间记忆方面,HoloLens也有着自己独特的解决方案. 在支持Tango的设备中,将一个虚拟物体放置在某 ...
- u3d_Shader_effects笔记3 half diffuse 和 ramp texture
1.前面的心情 每次写博客,先写心情也好,就当是小日记了吧.现在已经懒到不想动笔和纸来写日记了.近两天公司的活较少,晚上直接回来了,没有留公司.在公司看代码,不做工,就困... 哎,小辉哥家的老房子后 ...
- 嵌入式Linux驱动学习之路(七)Linux内核启动流程
编译的内核可能会很大,故这里可以压缩一下.而在内核文件中需要解压,所以就会有一段自解压代码. 在uboot启动内核的时候,调用了函数: thekernel(0,MACH_ID,params_addr ...
- luogu[1279]字串距离
题目描述 设有字符串X,我们称在X的头尾及中间插入任意多个空格后构成的新字符串为X的扩展串,如字符串X为”abcbcd”,则字符串“abcb□cd”,“□a□bcbcd□”和“abcb□cd□”都是X ...
- sql问题集合
1.sqlparameter @ 写在from前面
- BZOJ 3524: [Poi2014]Couriers
3524: [Poi2014]Couriers Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1905 Solved: 691[Submit][St ...