社区讨论
关于这题的的另一个切入
AT_arc168_e [ARC168E] Subsegments with Large Sums参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @m5fdnw6x
- 此快照首次捕获于
- 2025/01/02 21:44 去年
- 此快照最后确认于
- 2025/11/04 12:03 4 个月前
题解里我看似乎都是用 作为代价的 但是疑似如果令 为至少选 段 的此时最多能划分的段数 这个好像也是凸的
但是我在实现的时候 样例 4 没过 把二分答案的上界调成 就过了 这有道理吗????
CPP#include <bits/stdc++.h>
#define PR(x) printf(x ? "YES\n" : "NO\n")
#define pr(x) printf(x ? "Yes\n" : "No\n")
#define mk make_pair
#define pb emplace_back
#define fi first
#define se second
#define pii pair<int, int>
#define fore(i, u, v) for (int i = h[u], v = e[i].v; i; v = e[i = e[i].nxt].v)
#define all(x) x.begin(), x.end()
#define int long long
using namespace std;
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while (! isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48; ch = getchar(); }
return x * f;
}
const int maxn = 2.5e5 + 10;
int n, k, s, a[maxn];
pii f[maxn];
void work(int p) {
int l = 1;
for (int i = 1; i <= n; i ++) {
f[i] = {f[i - 1].fi + 1, f[i - 1].se};
while (a[i] - a[l] >= s) l ++;
if (a[i] - a[l - 1] >= s)
f[i] = max(f[i], {f[l - 1].fi + 1 - p, f[l - 1].se + 1});
}
}
int chk(int p) {
int l = -n, r = 0, ans = 0;
while (l < r) {
int mi = (l + r + 1) >> 1; work(mi);
if (f[n].se >= p) ans = f[n].fi + mi * p, l = mi;
else r = mi - 1;
}
return ans;
}
signed main() {
n = read(), k = read(), s = read();
for (int i = 1; i <= n; i ++) a[i] = read() + a[i - 1];
int l = 0, r = k;
// 这里 r 改了,原来是 n
while (l + 1 < r) {
int mi = l + r >> 1;
if (chk(mi) >= k) l = mi; else r = mi;
}
if (chk(r) >= k) cout << r; else cout << l;
return 0;
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...