P6109 [Ynoi2019] rprmq1
Luogu P6109 [Ynoi2009] rprmq1
题目背景
我谔谔
本题读入量约 13 MB,输出量约 7 MB,请选择合适的输入输出方法
题目描述
有一个
一次修改操作会给出
一次查询操作会给出
输入格式
第一行三个由空格分隔的整数
之后
之后
输出格式
输出
样例 #1
样例输入 #1
5 5 5
1 1 4 5 4
4 1 4 1 10
1 3 3 3 3
1 1 5 5 8
2 4 4 5 8
2 1 2 1
4 1 5 4
1 2 3 5
2 1 5 3
1 3 5 5
样例输出 #1
12
22
20
22
20
提示
Idea:apiadu,Solution:ccz181078,Code:apiadu,Data:apiadu&nzhtl1477
注意:本题采用捆绑测试,只有当你通过一个 subtask 中的所有测试点后,你才能拿到这个 subtask 的分数。
对于其中
对于另外
对于另外
对于另外
对于另外
对于
Solution
首先原问题是二维的,考虑压缩到一维加上时间轴的方式来解决。对于每一次修改操作
考虑线段树分治,用外层线段树表示时间这一轴,对于一个线段树上的节点
既然所有的询问都跨越
需要用到支持区间加,区间历史最值的线段树,参考P4314 CPU 监控。
#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
using ui64 = unsigned long long;
using Ldouble = long double;
#define fir first
#define sec second
#define MP make_pair
template<class T> void read(T &x) {
x = 0; bool flag = 0; char b = getchar();
while (!isdigit(b)) flag = b == '-' ? 1 : 0, b = getchar();
while (isdigit(b)) x = x * 10 + b - 48, b = getchar();
x = flag ? -x : x;
}
template<class T, class ...Args> void read(T &x, Args &...args) {
read(x), read(args...);
}
constexpr int _N = 5e5 + 5, _Q = 5e5 + 5;
int n, m, q;
#define LC (k << 1)
#define RC (k << 1 | 1)
#define mid ((l + r) >> 1)
template<class T> void Max(T &x, T y) { x = max(x, y); }
namespace SGT {
i64 maxn[_N << 2], hmax[_N << 2], tag1[_N << 2], tag2[_N << 2];
bool Isres[_N << 2];
void Pushup(int k) {
maxn[k] = max(maxn[LC], maxn[RC]);
hmax[k] = max(hmax[LC], hmax[RC]);
}
void Add(int k, i64 v1, i64 v2) {
Max(tag2[k], tag1[k] + v2);
Max(hmax[k], maxn[k] + v2);
maxn[k] += v1, tag1[k] += v1;
}
void Reset(int k) {
Add(LC, tag1[k], tag2[k]), Add(RC, tag1[k], tag2[k]);
Isres[k] = 1, hmax[k] = maxn[k], tag1[k] = tag2[k] = 0;
}
void Pushdown(int k) {
if (Isres[k]) {
Reset(LC), Reset(RC);
Isres[k] = 0;
}
Add(LC, tag1[k], tag2[k]), Add(RC, tag1[k], tag2[k]);
tag1[k] = tag2[k] = 0;
}
void Update(int k, int l, int r, int a, int b, i64 v) {
if (l > b || r < a) return ;
if (l >= a && r <= b) return Add(k, v, v);
Pushdown(k);
Update(LC, l, mid, a, b, v), Update(RC, mid + 1, r, a, b, v);
Pushup(k);
}
i64 Query(int k, int l, int r, int a, int b) {
if (l > b || r < a) return 0;
if (l >= a && r <= b) return hmax[k];
Pushdown(k);
return max(Query(LC, l, mid, a, b), Query(RC, mid + 1, r, a, b));
}
}
struct Query { int id, l, r, x, y; };
struct Node { int l, r; i64 v; };
vector<Query> que[_N << 2];
vector<Node> vec[_N];
void AddQuery(int k, int l, int r, Query v) {
if (v.l <= mid + 1 && v.r >= mid) {
que[k].push_back(v);
return ;
}
if (v.r <= mid) AddQuery(LC, l, mid, v);
else AddQuery(RC, mid + 1, r, v);
}
void Add(int x) {
for (auto s : vec[x]) SGT::Update(1, 1, n, s.l, s.r, s.v);
}
void Remove(int x) {
for (int i = vec[x].size() - 1; i >= 0; --i) {
auto s = vec[x][i];
SGT::Update(1, 1, n, s.l, s.r, -s.v);
}
}
i64 ans[_Q];
bool cmp1(Node A, Node B) { return A.v < B.v; }
bool cmp2(Query A, Query B) { return A.r < B.r; }
bool cmp3(Query A, Query B) { return A.l > B.l; }
void Solve(int k, int l, int r) {
for (int i = l; i <= mid; ++i) Add(i);
int p = 0, siz = que[k].size();
sort(que[k].begin(), que[k].end(), cmp2);
while (p < siz && que[k][p].r == mid) ++p;
for (int i = mid + 1; i <= r; ++i) {
Add(i);
if (i == mid + 1) SGT::Reset(1);
while (p < siz && que[k][p].r == i) {
Max(ans[que[k][p].id], SGT::Query(1, 1, n, que[k][p].x, que[k][p].y));
++p;
}
}
for (int i = r; i >= mid + 1; --i) Remove(i);
if (l != r) Solve(RC, mid + 1, r);
p = 0;
sort(que[k].begin(), que[k].end(), cmp3);
while (p < siz && que[k][p].l == mid + 1) ++p;
for (int i = mid; i >= l; --i) {
if (i == mid) SGT::Reset(1);
while (p < siz && que[k][p].l == i) {
Max(ans[que[k][p].id], SGT::Query(1, 1, n, que[k][p].x, que[k][p].y));
++p;
}
Remove(i);
}
if (l != r) Solve(LC, l, mid);
}
signed main() {
ios::sync_with_stdio(0); cout.tie(0);
read(n, m, q);
for (int i = 1; i <= m; ++i) {
int l, r, x, y, v;
read(l, x, r, y, v);
vec[l].push_back((Node){ x, y, v });
vec[r + 1].push_back((Node){ x, y, -v });
}
for (int i = 1; i <= q; ++i) {
int l, r, x, y;
read(l, x, r, y);
AddQuery(1, 1, n, (Query){ i, l, r, x, y });
}
for (int i = 1; i <= n; ++i)
sort(vec[i].begin(), vec[i].end(), cmp1);
Solve(1, 1, n);
for (int i = 1; i <= q; ++i) cout << ans[i] << '\n';
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2022-07-11 P2466 [SDOI2008] Sue 的小球
2022-07-11 #P2088. 上升序列
2022-07-11 #P2056. ABCD
2022-07-11 #P2030. 交错匹配
2022-07-11 #P2057. 游戏