#include #include #include #include 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; }