CF1101F Trucks and Cities 题解
来点神秘做法,复杂度是对的,而且会比 DP 优。
考虑逐个二分,发现复杂度
考虑加点剪枝,发现若某段行程的答案
此时只会在每个前缀最大值处二分,发现答案递增还是会寄,
于是使用小杀招,shuffle 所有行程,此时前缀最大值只有
#include <cstdio>
#include <random>
#include <algorithm>
#define int long long
using namespace std;
int n, m, z, R, a[250050];
struct Q
{
int s, t, c, r;
} q[250050];
bool C(int o, int k)
{
for (int i = q[o].s, z = 0, p = 0; i < q[o].t; ++i)
{
if (q[o].c * (a[i + 1] - a[i]) > k)
return 0;
if (z + q[o].c * (a[i + 1] - a[i]) > k)
{
if (++p > q[o].r)
return 0;
z = q[o].c * (a[i + 1] - a[i]);
}
else
z += q[o].c * (a[i + 1] - a[i]);
}
return 1;
}
signed main()
{
scanf("%lld%lld", &n, &m);
for (int i = 1; i <= n; ++i)
scanf("%lld", a + i);
for (int i = 1; i <= m; ++i)
scanf("%lld%lld%lld%lld", &q[i].s, &q[i].t, &q[i].c, &q[i].r), R = max(R, q[i].c * (a[q[i].t] - a[q[i].s]));
shuffle(q + 1, q + m + 1, default_random_engine());
for (int i = 1, l, r, M; i <= m; ++i)
if (!C(i, z))
{
for (l = z, r = R; l <= r;)
if (C(i, M = l + r >> 1))
r = M - 1;
else
l = M + 1;
z = l;
}
printf("%lld", z);
return 0;
}
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具