专栏文章
题解:P10730 [NOISG 2023 Qualification] Burgers
P10730题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miq5ma41
- 此快照首次捕获于
- 2025/12/03 23:20 3 个月前
- 此快照最后确认于
- 2025/12/03 23:20 3 个月前
题意:给定数组 ,求两个整数使得 最大且满足 。
给这个式子换个形式:。
得到 。
发现这相当于给一些线段,求线段下方最大点。
建出凸包简单维护即可。
CPP
#include <bits/stdc++.h>
using namespace std;
inline long long read(void) {
long long x = 0, f = 1; char c = getchar();
while (c > '9' || c < '0') {
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + c - 48, c = getchar();
return x * f;
}
struct node {
long double k, b, bg;
} stk[100005];
struct line {
long double k, b;
friend bool operator< (line x, line y) {
if (x. k == y. k) return x. b < y. b;
return x. k > y. k;
}
} lne[100005];
long long n, cnt, cct, c[100005], a[100005], b[100005], ans;
int main(void) {
n = read();
for (int i = 1; i <= n; i++) c[i] = read();
for (int i = 1; i <= n; i++) a[i] = read();
for (int i = 1; i <= n; i++) b[i] = read();
if (a[1] < b[1]) for (int i = 1; i <= n; i++) swap(a[i], b[i]);
for (int i = 1; i <= n; i++) lne[i]. k = (long double)1 - (long double)(a[i]) / b[i], lne[i]. b = (long double)c[i] / b[i];
sort(lne + 1, lne + 1 + n);
for (int i = 1; i <= n; i++)
if (i == 1 || lne[i]. k != lne[i - 1]. k)
lne[++cct] = lne[i];
n = cct;
stk[++cnt] = {lne[1]. k, lne[1]. b, 0};
for (int i = 2; i <= n; i++) {
while (cnt && (lne[i]. b - stk[cnt]. b) / (stk[cnt]. k - lne[i]. k) <= stk[cnt]. bg) cnt--;
if (!cnt) stk[++cnt] = {lne[i]. k, lne[i]. b, 0};
else cnt++, stk[cnt] = {lne[i]. k, lne[i]. b, (lne[i]. b - stk[cnt - 1]. b) / (stk[cnt - 1]. k - lne[i]. k)};
}
for (int i = 1; i <= cnt; i++) {
if (i == cnt || ceill(stk[i]. bg) < stk[i + 1]. bg) ans = max(ans, (long long)(ceill(stk[i]. bg) * stk[i]. k + stk[i]. b));
if (i < cnt && floor(stk[i + 1]. bg) >= stk[i]. bg) ans = max(ans, (long long)((floor(stk[i + 1]. bg)) * stk[i]. k + stk[i]. b));
}
printf("%lld", ans);
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...