NC15162 小H的询问
题目
题目描述
小H给你一个数组 \(a\) ,要求支持以下两种操作:
0 l r \((1 \leq l \leq r \leq n)\),询问区间 \([l,r]\) 中权值和最大的有效子区间的权值和,一个子区间被认为是有效的当且仅当这个子区间中没有两个相邻的偶数或者奇数。
1 x v \((1 \leq x \leq n,-10^9 \leq v \leq 10^9)\) ,将 \(a[x]\) 的值修改为 \(v\) 。
输入描述
第一行读入两个正整数 \(n,m(1 \leq n,m \leq 10^5)\) 第二行读入 \(n\) 个整数,第 \(i\) 个表示 \(a[i](-10^9 \leq a[i] \leq 10^9)\) 接下来 \(m\) 行,每行三个数表示操作,描述见题目描述。
输出描述
输出每个询问的答案。
示例1
输入
10 10
-9 -8 -8 -8 2 -7 -5 2 2 3
0 3 5
0 4 4
0 2 4
1 6 6
1 1 6
1 5 9
0 1 2
1 5 -8
0 2 4
1 3 -2
输出
2
-8
-8
6
-8
题解
知识点:线段树。
见到这种连续段最大值的,先维护三个信息,区间有效最大值 \(mx\) 、区间左端点开始的有效最大值 \(lmx\) 、区间右端点开始的有效最大值 \(rmx\) ,用以维护合并。
继续考虑,合并需要端点的奇偶性相反才可行,因此需要维护左端点奇偶性 \(lodd\) 、右端点奇偶性 \(rodd\) 。
同时,考虑到 \(lmx,rmx\) 合并时会出现跨越两段的情况,需要再维护一个区间权值和 \(sum\) 。当左右可跨越时,可以用 \(lmx\) 与左子区间 \(sum\) 加 右子区间 \(lmx\) 取最大值, \(rmx\) 同理。需要注意, \(sum\) 不能用 \(lmx,rmx\) 替代,因为权值是有正有负的, \(sum\) 不一定是 \(lmx,rmx\) ,必须多维护一个 \(sum\) 。
对于 \(sum\) ,我们还需要来判断整个区间是否为有效区间,从而判断 \(sum\) 是否可用。为了少设一个变量保存区间是否整个有效(当然设了也行,写起来容易点),我们设 \(sum\) 初值为极小值 \(-10^{18}\) 的表示无效值,更新时取 \(sum\) 与左右子区间的 \(sum\) 的和的最大值即可。显然,左右子区间存在一个无效值,则区间的值一定无效。
因此,区间信息要维护 \(mx,lmx,rmx,lodd,rodd,sum\) 。
合并时, \(lodd,rodd\) 直接继承即可,接下来分两步:
\(mx\) 取左右子区间 \(mx\) 的最大值, \(lmx,rmx\) 直接继承。
若左子区间 \(rodd\) 和右子区间 \(lodd\) 不同,则在第一步的基础上考虑跨越两段的情况。
\(mx\) 需要再与左子区间 \(rmx\) 加右子区间 \(lmx\) 的和取最大值。
\(lmx,rmx\) 考虑特殊情况,已经在考虑维护信息的时候分析过了。
\(sum\) 也分析过了。
修改时,直接修改即可,过程非常朴素,就不讲了。
另外,由于线段树结构的问题,我需要多加一个表示区间是否存在的 \(exist\) 以用来合并无效区间时特判,这个完全可以用先判断后递归避免,但是我懒23333。
时间复杂度 \(O((n+m) \log n)\)
空间复杂度 \(O(n)\)
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct T {
bool exist = 0; // 区间是否存在
ll mx = -1e18; // 有效区间最大值
ll sum = -1e18; // 区间权值和(区间权值和不能用 lmx,rmx 替代)
bool lodd = 0, rodd = 0; // 左/右端点的奇偶性
ll lmx = -1e18, rmx = -1e18; // 从左/右端点出发的最大值
friend T operator+(const T &a, const T &b) {
if (!a.exist) return b;
if (!b.exist) return a;
T x = T();
x.exist = 1;
x.mx = max(a.mx, b.mx);
x.lodd = a.lodd, x.rodd = b.rodd;
x.lmx = a.lmx, x.rmx = b.rmx;
if (a.rodd ^ b.lodd) {
x.mx = max(x.mx, a.rmx + b.lmx);
x.sum = max(x.sum, a.sum + b.sum); // 取最大值,防止溢出
x.lmx = max(x.lmx, a.sum + b.lmx);
x.rmx = max(x.rmx, a.rmx + b.sum);
}
return x;
}
};
struct F {
ll upd;
T operator()(const T &x) {
return{
1,
upd,
upd,
(bool)(upd % 2),(bool)(upd % 2),
upd,upd,
};
}
};
template<class T, class F>
class SegmentTree {
int n;
vector<T> node;
void update(int rt, int l, int r, int x, F f) {
if (r < x || x < l) return;
if (l == r) return node[rt] = f(node[rt]), void();
int mid = l + r >> 1;
update(rt << 1, l, mid, x, f);
update(rt << 1 | 1, mid + 1, r, x, f);
node[rt] = node[rt << 1] + node[rt << 1 | 1];
}
T query(int rt, int l, int r, int x, int y) {
if (r < x || y < l) return T();
if (x <= l && r <= y) return node[rt];
int mid = l + r >> 1;
return query(rt << 1, l, mid, x, y) + query(rt << 1 | 1, mid + 1, r, x, y);
}
public:
SegmentTree(const vector<T> &src) { init(src); }
void init(const vector<T> &src) {
assert(src.size() >= 2);
n = src.size() - 1;
node.assign(n << 2, T());
function<void(int, int, int)> build = [&](int rt, int l, int r) {
if (l == r) return node[rt] = src[l], void();
int mid = l + r >> 1;
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
node[rt] = node[rt << 1] + node[rt << 1 | 1];
};
build(1, 1, n);
}
void update(int x, F f) { update(1, 1, n, x, f); }
T query(int x, int y) { return query(1, 1, n, x, y); }
};
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, m;
cin >> n >> m;
vector<T> a(n + 1);
for (int i = 1;i <= n;i++) {
int x;
cin >> x;
a[i] = {
1,
x,
x,
(bool)(x % 2),(bool)(x % 2),
x,x,
};
}
SegmentTree<T, F> sgt(a);
while (m--) {
int op;
cin >> op;
if (op == 0) {
int l, r;
cin >> l >> r;
cout << sgt.query(l, r).mx << '\n';
}
else {
int x, v;
cin >> x >> v;
sgt.update(x, { v });
}
}
return 0;
}
NC15162 小H的询问的更多相关文章
- Wannafly挑战赛10 D 小H的询问(线段树)
题目链接 Problem D 这个题类似 SPOJ GSS3 做过那个题之后其实就可以秒掉这题了. 考虑当前线段树维护的结点 在那道题的基础上,这个题要多维护几个东西,大概就是左端点的奇偶性,右端点 ...
- BZOJ 3781: 小B的询问
3781: 小B的询问 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 643 Solved: 435[Submit][Status][Discuss ...
- hihocoder 1347 小h的树上的朋友
传送门 时间限制:18000ms单点时限:2000ms内存限制:512MB 描述 小h拥有$n$位朋友.每位朋友拥有一个数值$V_i$代表他与小h的亲密度.亲密度有可能发生变化.岁月流逝,小h的朋友们 ...
- Bzoj 3781: 小B的询问 莫队,分块,暴力
3781: 小B的询问 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 426 Solved: 284[Submit][Status][Discuss ...
- 2018.07.01 洛谷小B的询问(莫队)
P2709 小B的询问 题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数 ...
- 小H和密码
链接:https://www.nowcoder.com/acm/contest/72/B来源:牛客网 题目描述 小H在击败怪兽后,被一个密码锁挡住了去路 密码锁由N个转盘组成,编号为1 ...
- AC日记——小B的询问 洛谷 P2709
小B的询问 思路: 水题: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 50005 #define ll ...
- BZOJ_3781_小B的询问_莫队
BZOJ_3781_小B的询问_莫队 Description 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值 ...
- hihocoder-1347 小h的树上的朋友(lca+线段树)
题目链接: 小h的树上的朋友 时间限制:18000ms 单点时限:2000ms 内存限制:512MB 描述 小h拥有n位朋友.每位朋友拥有一个数值Vi代表他与小h的亲密度.亲密度有可能发生变化. 岁月 ...
- 洛谷——P2709 小B的询问
P2709 小B的询问 莫队算法,弄两个指针乱搞即可 这应该是基础莫队了吧 $x^2$可以拆成$((x-1)+1)^2$,也就是$(x-1)^2+1^2+2\times (x-1)$,那么如果一个数字 ...
随机推荐
- Linux进阶命令-grep
Linux进阶命令----grep 目录 Linux进阶命令----grep grep 命令介绍 grep命令格式 常用选项 模式部分 匹配字符: 匹配次数: 位置锚定: grep 命令介绍 Linu ...
- [转帖]20--Deployment常规操作
https://www.cnblogs.com/caodan01/p/15309966.html 目录 一.Deployment滚动更新 1.更新配置清单 2.设置镜像 kubectl set ima ...
- [转帖]《Linux性能优化实战》笔记(21)—— 网络性能优化思路
一. 确定优化目标 优化前,我会先问问自己,网络性能优化的目标是什么?实际上,虽然网络性能优化的整体目标,是降低网络延迟(如 RTT)和提高吞吐量(如BPS 和 PPS),但具体到不同应用中,每个指标 ...
- [转帖]XCopy命令实现增量备份
https://www.cnblogs.com/pachongshangdexuebi/p/5051977.html xcopy XCOPY是COPY的扩展,可以把指定的目录连文件和目录结构一并拷贝, ...
- [转帖]@nginx多server及使用优化(php)
文章目录 一.nginx多server优先级 二.禁止IP访问页面 三.nginx的包含include 四.nginx 路径的alias和root 1.配 ...
- Oracle TNS 异常问题处理
今天下午快下班时同事找我说自己的性能测试Oracle数据库 连不上了. 然后自己连上去简单看了一下. 因为已经是事后了, 所以没有截图,只通过文字说明. 环境说明:Win2012r2 + Oracle ...
- Linux 通过yum 方式离线下载依赖rpm包的操作步骤
离线下载依赖rpm包的方法 1.简单获取依赖关系 yum deplist rpm-build 注意 deplist 为依赖项目 我在arm 上面简单跑一下结果为 package: rpm-build- ...
- 高性能MySQL实战(二):索引 | 京东物流技术团队
我们在上篇 高性能MySQL实战(一):表结构 中已经建立好了表结构,这篇我们则是针对已有的表结构和搜索条件为表创建索引. 1. 根据搜索条件创建索引 我们还是先将表结构的初始化 SQL 拿过来: C ...
- 离开页面关闭video标签
<video src="./play.mp4" id="maskmore_1" controls="controls" autopla ...
- 一个思路:实现 golang 中的 `__file__` `__line__` 宏
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 测试 zaplog 发现,开启 caller 的调用,会使 ...