专题二树形结构 E - Can you answer these queries V
- 题目
You are given a sequence A[1], A[2], ..., A[N] . ( |A[i]| <= 10000 , 1 <= N <= 10000 ). A query is defined as follows: Query(x1,y1,x2,y2) = Max { A[i]+A[i+1]+...+A[j] ; x1 <= i <= y1 , x2 <= j <= y2 and x1 <= x2 , y1 <= y2 }. Given M queries (1 <= M <= 10000), your program must output the results of these queries.
Input
The first line of the input consist of the number of tests cases <= 5. Each case consist of the integer N and the sequence A. Then the integer M. M lines follow, contains 4 numbers x1, y1, x2 y2.
Output
Your program should output the results of the M queries for each test case, one query per line.
Example
Input: 2 6 3 -2 1 -4 5 2 2 1 1 2 3 1 3 2 5 1 1 1 1 1 1 1 Output: 2 3 1
- 思路
这题没有修改,和A相比的区别主要是前后端点不定
A题:https://www.cnblogs.com/Benincasa/p/15866592.html
两个区间不相交时,最大连续和是x1,y1的最大后缀和,加上y1,x2的总和,再加上x2,y2的最大前缀和
两个区间相交时有四种情况,一种情况下和不相交的时候方法一样,另外三种分别是x2,y1的最大连续和,x1,y1的最大连续和,x2,y2的最大连续和 - 代码
lmin是之前写别的思路的时候加的,没啥用
#include<cstdio> #include<iostream> #include<string> #include<cstring> #include<algorithm> using namespace std; #define clear(a,x) memset(a,x,sizeof(a)) #define ll long long const int M=4e5; struct Node { int lsum, lmin, rsum, sum, maxx; }ss[M]; int a[M << 2]; int n,q,ca,ans; void up(int p) { ss[p].sum = ss[p << 1].sum + ss[(p << 1) + 1].sum; ss[p].lsum = max(ss[p << 1].lsum, ss[p << 1].sum + ss[p << 1 | 1].lsum); ss[p].lmin = min(ss[p << 1].lmin, ss[p << 1].sum + ss[p << 1 | 1].lmin); ss[p].rsum = max(ss[p << 1 | 1].rsum, ss[p << 1 | 1].sum + ss[p << 1].rsum); ss[p].maxx = max(max(ss[p << 1].maxx, ss[p << 1 | 1].maxx), ss[p << 1].rsum + ss[p << 1 | 1].lsum); } void build(int s, int t, int p) { if (s == t) { ss[p].lsum = ss[p].lmin = ss[p].rsum = ss[p].maxx = ss[p].sum = a[s]; return; } int m = s + ((t - s) >> 1); build(s, m, p << 1), build(m + 1, t, p << 1 | 1); up(p); } //void change(int x, int c, int s, int t, int p) //{ // int m = s + ((t - s) >> 1); // if (s == x && s == t) { // ss[p].maxx = ss[p].lsum = ss[p].rsum = ss[p].sum = c; // return; // } // if (x <= m) change(x, c, s, m, p << 1); else change(x, c, m+1, t, p << 1 | 1); // up(p); //} Node query(int l, int r, int s, int t, int p){ if (l <= s && t <= r) return ss[p]; int m = s + ((t - s) >> 1); if (m >= r) return query(l, r, s, m, p << 1) ; else if (m < l) return query(l, r, m + 1, t, p << 1 | 1); else { Node ls = query(l, r, s, m, p << 1); Node rs = query(l, r, m + 1, t, p << 1 | 1); Node ans ; ans.maxx = max(max(ls.maxx, rs.maxx), ls.rsum + rs.lsum); ans.lsum = max(ls.lsum, ls.sum + rs.lsum); ans.lmin = min(ls.lmin, ls.sum + rs.lmin); ans.rsum = max(rs.rsum, rs.sum + ls.rsum); ans.sum = ls.sum + rs.sum; return ans; } } int main() { scanf("%d",&ca); while(ca--) { scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } build(1,n,1); scanf("%d",&q); int x1,y1,x2,y2; while (q--) { ans = 0; cin >> x1 >> y1 >> x2 >> y2; if(y1 < x2) { ans = query(x1,y1,1,n,1).rsum + query(x2,y2,1,n,1).lsum + query(y1,x2,1,n,1).sum; ans = ans - a[y1] - a[x2]; } else { int a1 = query(x2,y1,1,n,1).maxx; int a2 = query(x1,x2,1,n,1).rsum + query(y1,y2,1,n,1).lsum + query(x2,y1,1,n,1).sum; a2 = a2 - a[y1] - a[x2]; int a3 = query(x1,x2,1,n,1).rsum + query(x2,y1,1,n,1).lsum - a[x2]; int a4 = query(x2,y1,1,n,1).rsum + query(y1,y2,1,n,1).lsum - a[y1]; ans = max(max(max(a1, a2), a3), a4); } cout << ans << endl; } } return 0; }