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个点,问 ...
随机推荐
- ASP.NET Core 1.0 安装并发布到Centos 7.2 使用jexus 5.8.2
安装运行环境 sudoyuminstall libunwind libicu 下载.net core https://www.microsoft.com/net/download 下载完后上传文件 安 ...
- docker-5 docker仓库
docker部署环境:CentOS release 6.5 (Final) Docker配置文件:/etc/sysconfig/docker 重要参数解释: -H 表示Docker Daemon绑定 ...
- poj 2104 K-th Number(可持久线段树)
K-th Number 持久化:http://www.cnblogs.com/tedzhao/archive/2008/11/12/1332112.html 结构:http://www.docin.c ...
- Flex 布局教程:语法篇[转]
网页布局(layout)是CSS的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中 ...
- 玩转Windows Azure存储服务——网盘
存储服务是除了计算服务之外最重要的云服务之一.说到云存储,大家可以想到很多产品,例如:AWS S3,Google Drive,百度云盘...而在Windows Azure中,存储服务却是在默默无闻的工 ...
- C#语言数据总结
整数类型 sbyte -128~127之间 byte 0~255 short(Int16) -32768~32768 ushort(UInt16) 0~65535 Int (Int32) ...
- 常用的SQL 语句
一.简单查询语句 1. 查看表结构 SQL>DESC emp; 2. 查询所有列 SQL>SELECT * FROM emp; 3. 查询指定列 SQL>SELECT empmo, ...
- Vijos1392拼拼图的小衫[背包DP|二维信息DP]
背景 小杉的幻想来到了经典日剧<死亡拼图>的场景里……被歹徒威胁,他正在寻找拼图(-.-干嘛幻想这么郁闷的场景……). 突然广播又响了起来,歹徒竟然又有了新的指示. 小杉身为新一代的汤浅, ...
- BigDecimal.ROUND_HALF_XXX的各种用法
在银行.帐户.计费等领域,BigDecimal提供了精确的数值计算.其中8种舍入方式值得掌握. 1.ROUND_UP 舍入远离零的舍入模式. 在丢弃非零部分之前始终增加数字(始终对非零舍弃部分前面的数 ...
- PHPstudy和ecshop的安装和使用
PHPstudy和ecshop: phpStudy是一个PHP调试环境的程序集成包. 该程序包集成最新的Apache+PHP+MySQL+phpMyAdmin+ZendOptimizer,一次性安装, ...