Files
python/TangDou/AcWing/SegmentTree/SPOJ_GSS5.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

86 lines
2.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 10010;
int a[N];
struct Node {
int l, r;
int sum, tmax, lmax, rmax;
} tr[N << 2];
void calc(Node &u, Node &l, Node &r) {
u.sum = l.sum + r.sum; // 区间和
u.tmax = max({l.tmax, r.tmax, l.rmax + r.lmax}); // 子区间最大值
u.lmax = max(l.lmax, l.sum + r.lmax); // 左前缀最大值
u.rmax = max(r.rmax, r.sum + l.rmax); // 右后缀最大值
}
void pushup(int u) {
calc(tr[u], tr[u << 1], tr[u << 1 | 1]);
}
void build(int u, int l, int r) {
tr[u] = {l, r, 0, 0, 0, 0};
if (l == r) {
tr[u].sum = tr[u].tmax = tr[u].lmax = tr[u].rmax = a[l];
return;
}
int mid = (tr[u].l + tr[u].r) >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
Node query(int u, int l, int r) {
if (l > tr[u].r || r < tr[u].l) return {}; // 递归出口,不在我管辖范围内的情况,返回0
if (l <= tr[u].l && tr[u].r <= r) return tr[u];
int mid = (tr[u].l + tr[u].r) >> 1;
if (r <= mid) return query(u << 1, l, r);
if (l > mid) return query(u << 1 | 1, l, r);
Node a = query(u << 1, l, r), b = query(u << 1 | 1, l, r), c;
calc(c, a, b);
return c;
}
int main() {
// 加快读入
ios::sync_with_stdio(false), cin.tie(0);
int T, n, m;
cin >> T;
while (T--) {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
build(1, 1, n);
cin >> m;
while (m--) {
int x1, y1, x2, y2, res;
Node a, b, c;
cin >> x1 >> y1 >> x2 >> y2;
if (y1 < x2) { // 这里不能取等 不然边界会被算2次
a = query(1, x1, y1);
b = query(1, x2, y2);
c = query(1, y1 + 1, x2 - 1);
res = a.rmax + c.sum + b.lmax;
} else {
res = query(1, x2, y1).tmax; // 最大子序列和出现在交集中
a = query(1, x1, x2 - 1);
b = query(1, x2, y2);
res = max(res, a.rmax + b.lmax);
a = query(1, x1, y1);
b = query(1, y1 + 1, y2);
res = max(res, a.rmax + b.lmax);
}
printf("%d\n", res);
}
}
return 0;
}