luoguP1253 扶苏的问题
给定长度为n的序列A,有如下3种操作:
- 1 l r x,将区间[l,r]中的每个数都修改为x。
- 2 l r x,将区间[l,r]中的每个数都加上x。
- 3 l r,查询区间[l,r]内的最大值。
分析:设置2个懒标记,先处理赋值标记,再处理增加标记。
#include <bits/stdc++.h>
using llong = long long;
const llong inf = 1e18;
// LazySegmentTree模板...
struct Tag {
llong set;
llong add;
Tag(llong s=inf, llong a=inf):set(s),add(a) {}
void apply(Tag t) {
if (t.set != inf) {
set = t.set;
add = inf;
}
if (t.add != inf) {
if (add == inf) {
add = t.add;
} else {
add += t.add;
}
}
}
friend std::ostream& operator<<(std::ostream &out, Tag &tag) {
out << "tag:(" << tag.set << "," << tag.add << ")";
return out;
}
};
struct Info {
llong max;
Info(llong a=-inf):max(a) {}
void apply(Tag t) {
if (t.set != inf) {
max = t.set;
}
if (t.add != inf) {
max += t.add;
}
}
friend Info operator+(const Info &a, const Info &b) {
Info ans;
ans.max = std::max(a.max, b.max);
return ans;
}
friend std::ostream& operator<<(std::ostream &out, Info &info) {
out << "info:(" << info.max << ")";
return out;
}
};
void solve() {
int n, m;
std::cin >> n >> m;
std::vector<llong> A(n);
for (int i = 0; i < n; i++) {
std::cin >> A[i];
}
LazySegmentTree<Info,Tag> tr(A);
for (int i = 0; i < m; i++) {
int op, l, r, x;
std::cin >> op >> l >> r;
if (op == 1) {
std::cin >> x;
tr.rangeApply(l-1, r, Tag(x, inf));
} else if (op == 2) {
std::cin >> x;
tr.rangeApply(l-1, r, Tag(inf, x));
} else if (op == 3) {
std::cout << tr.rangeQuery(l-1, r).max << "\n";
}
}
}
int main() {
std::cin.tie(0)->sync_with_stdio(0);
int t = 1;
while (t--) solve();
return 0;
}
浙公网安备 33010602011771号