【题解】火枪打怪
思路
求最小值,很有可能是二分,我们再看数据范围,就应该往这方面想。
其实这道题最坑的还是 check
, 是真的不好想。
我们不难写出一个 check
。
bool check(int x) {
int sum = 0;
for (int i = 1; i <= n; i++) b[i] = a[i];
for (int i = n; i >= 1; i--) {
if (b[i] < 0)
continue;
int h = ceil((b[i] + 1) * 1.0 / x);
b[i] -= h * x;
for (int j = 1; j < i; j++) b[j] -= max(0ll, x - (i - j) * (i - j)) * h;
sum += h;
}
return sum <= m;
}
但是这必定超时,所以我们要想办法优化我们的 check
。
我们可以化简式子得到:
我们假设射击范围为 r
,
所以溅射伤害为:
所以我们只需维护
就有代码:
bool check(int p) {
for (int i = 1; i <= n; i++)
b[i] = 0;
int r = sqrt(p) + 1, s = 0, v1 = 0, v2 = 0, sum = 0;
for (int i = n; i >= 1; i--) {
if (i + r <= n && b[i + r]) {
s -= b[i + r];
v1 -= (i + r) * (i + r) * b[i + r];
v2 -= (i + r) * b[i + r];
}
int hp = s * p - v1 - i * i * s + v2 * i * 2;
if (a[i] >= hp) {
b[i] += (a[i] - hp) / p + 1;
s += b[i];
v1 += i * i * b[i];
v2 += i * b[i];
sum += b[i];
}
if (sum > m)
break;
}
return sum <= m;
}
其时间复杂度为
Code
#include <cstdio>
#include <cmath>
#include <iostream>
#define int long long
using namespace std;
const int MAXN = 5e5 + 5;
int n, m;
int a[MAXN];
int b[MAXN];
bool check(int p) {
for (int i = 1; i <= n; i++)
b[i] = 0;
int r = sqrt(p) + 1, s = 0, v1 = 0, v2 = 0, sum = 0;
for (int i = n; i >= 1; i--) {
if (i + r <= n && b[i + r]) {
s -= b[i + r];
v1 -= (i + r) * (i + r) * b[i + r];
v2 -= (i + r) * b[i + r];
}
int hp = s * p - v1 - i * i * s + v2 * i * 2;
if (a[i] >= hp) {
b[i] += (a[i] - hp) / p + 1;
s += b[i];
v1 += i * i * b[i];
v2 += i * b[i];
sum += b[i];
}
if (sum > m)
break;
}
return sum <= m;
}
signed main() {
scanf("%lld %lld", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
int l = 1, r = 1e15;
while (l < r) {
int mid = (l + r) >> 1;
if (check(mid))
r = mid;
else
l = mid + 1;
}
printf("%lld", l);
return 0;
}
本文来自博客园,作者:zhou_ziyi,转载请注明原文链接:https://www.cnblogs.com/zhouziyi/p/16526559.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通