1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| #include <iostream> #include <algorithm> #include <vector> #include <stack> using namespace std; using LL = long long; const int N = 2e5; const LL INF = -1e15; int t, n, a[N], pg[N], ng[N]; LL ps[N], ss[N]; void nextGreater() { stack<int> s; for (int i = 0; i < n; ++i) { ng[i] = n; while (s.size() && a[s.top()] < a[i]) { ng[s.top()] = i; s.pop(); } s.push(i); } } void prevGreater() { stack<int> s; for (int i = n - 1; i >= 0; --i) { pg[i] = -1; while (s.size() && a[s.top()] < a[i]) { pg[s.top()] = i; s.pop(); } s.push(i); } }
LL query(vector<LL> &tree, int u, int l, int r, int L, int R) { if (R < l || L > r) return INF; if (L <= l && r <= R) return tree[u]; int mid = (l + r) >> 1; LL ans = INF; ans = max(ans, query(tree, u << 1, l, mid, L, R)); ans = max(ans, query(tree, u << 1 | 1, mid + 1, r, L, R)); return ans; } int main() { scanf("%d", &t); while (t--) { scanf("%d", &n); for (int i = 0; i < n; ++i) scanf("%d", &a[i]); ps[0] = a[0]; for (int i = 1; i < n; ++i) ps[i] = ps[i - 1] + a[i]; ss[n - 1] = a[n - 1]; for (int i = n - 2; i >= 0; --i) ss[i] = ss[i + 1] + a[i]; int _n = n; while (__builtin_popcount(_n) != 1) _n++; vector<LL> pt(2 * _n, INF), st(2 * _n, INF); for (int i = 0; i < n; ++i) pt[_n + i] = ps[i], st[_n + i] = ss[i]; for (int i = _n - 1; i >= 1; --i) { pt[i] = max(pt[i << 1], pt[i << 1 | 1]); st[i] = max(st[i << 1], st[i << 1 | 1]); } nextGreater(); prevGreater(); bool flag = true; for (int i = 0; i < n; ++i) { LL rightMax = query(pt, 1, 0, _n - 1, i + 1, ng[i] - 1) - ps[i]; if (rightMax > 0) { flag = false; break; } LL leftMax = query(st, 1, 0, _n - 1, pg[i] + 1, i - 1) - ss[i]; if (leftMax > 0) { flag = false; break; } } printf(flag ? "YES\n" : "NO\n"); } return 0; }
|