标签:const 递增 blocks bottom code mes cin lock ase
单调栈
可以发现子序列的平均数不小于k就可以使子序列的每个数都不小于k
将每个数减去k,则子序列之和非负即可
记 si = a1 + a2 +....+ ai - k*i
考虑序列的两个端点 l, r
对于 l: l1 < l2 && sl1 <= sl2, 则l1 比 l2 优
对于 r: r1 < r2 && sr1 <= sr2 则r2 比 r1 优
从0到n 将可能最优 l 加入单调栈中,可以发现栈是单调递增的
从n到1 的可能最优 r 的是单调递减的
每次将当前栈中满足sr - sl ≥ 0的 l 都弹出,最后一个被弹出的就是最优的l
而且对与更小的 r,它的值会更大,所以被弹出的l更不会用到
#include <bits/stdc++.h> using namespace std; const int N = 1e6 + 5; typedef long long LL; int n, m, a[N], k, ans, zhan[N], top; LL s[N]; void Solve() { ans = top = 0; zhan[++top] = 0; for (int i = 1; i <= n; i++) { s[i] = s[i - 1] + a[i] - k; if (s[i] < s[zhan[top]]) zhan[++top] = i; } for (int i = n; i; i--) { while (s[i] - s[zhan[top]] >= 0 && top) top--; ans = max(ans, i - zhan[top + 1]); } cout << ans << " "; } int main() { cin >> n >> m; for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int i = 1; i <= m; i++) { scanf("%d", &k); Solve(); } return 0; }
标签:const 递增 blocks bottom code mes cin lock ase
原文地址:https://www.cnblogs.com/ympc2005/p/12310925.html