CF1691D 题解
CF1691D link
Rd795 题解滞销,帮帮我(误
首先对于这个式子,不难注意到左边的
那么可以变成枚举一个最大值
经典把
问题变成在
问题变成如何对于一个
可以考虑把这
这样每个数在链表上的左右的数就是第一个大于(等于)它的值了,因为比它小都删掉了,换句话说它们直接确定了
关于一个小细节:如果两个数值相等的时候,枚举的时候是有序的,不能保证 为什么?留作思考题吧。
在码量上我已经赢太多了
// Problem: D. Max GEQ Sum
// From: Codeforces - CodeCraft-22 and Codeforces Round #795 (Div. 2)
// URL: https://codeforces.com/contest/1691/problem/D
// Time: 2022-05-31 22:35
// Author: lingfunny
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int mxn = 2e5+10;
int n, a[mxn], tot, pos[mxn], lg[mxn], p[mxn], L[mxn], R[mxn];
LL s[mxn], mis[20][mxn], mxs[20][mxn];
inline LL Qmi(int L, int R) {
int k = lg[R-L+1];
return min(mis[k][L], mis[k][R-(1<<k)+1]);
}
inline LL Qmx(int L, int R) {
int k = lg[R-L+1];
return max(mxs[k][L], mxs[k][R-(1<<k)+1]);
}
inline void solve() {
scanf("%d", &n);
for(int i = 1; i <= n; ++i) scanf("%d", a+i), s[i] = s[i-1] + a[i], p[i] = i, L[i] = i-1, R[i] = i+1;
for(int i = 1; i <= n; ++i) mis[0][i] = s[i-1];
for(int i = 1; i <= n; ++i) mxs[0][i] = s[i];
for(int i = 1; i <= lg[n]; ++i)
for(int j = 1; j <= n - (1<<i) + 1; ++j)
mis[i][j] = min(mis[i-1][j], mis[i-1][j+(1<<(i-1))]),
mxs[i][j] = max(mxs[i-1][j], mxs[i-1][j+(1<<(i-1))]);
sort(p+1, p+n+1, [&](int x, int y) { return a[x] < a[y]; });
for(int i = 1; i <= n; ++i) {
int u = p[i];
R[L[u]] = R[u], L[R[u]] = L[u];
if(a[u] < Qmx(u, R[u]-1) - Qmi(L[u]+1, u)) return puts("NO"), void();
}
puts("YES");
}
int main() {
lg[0] = -1;
for(int i = 1; i < mxn; ++i) lg[i] = lg[i>>1] + 1;
int tt;
scanf("%d", &tt);
while(tt--) solve();
}