原题链接
- 题解:解决了历史遗留问题。很显然的是,这样操作总和不会变,然后所有 gcd 的可能的取值都是会是 sum 的因子,所以可以 O(√sum) 的时间复杂度来枚举 gcd,然后 O(n) 遍历用最小操作来看是否是小于 k,最后取最大。
- 代码:
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const ll N = 1e6 + 9, mod = 1e9 + 7;
ll a[N];
ll b[N];
ll sum = 0;
ll n, k;
ll ans;
void check(ll p) {
ll ssum = 0;
for (ll i = 1; i <= n; i++) {
b[i] = a[i] % p;
}
sort(b + 1, b + 1 + n);
ll sub = 0;
ll add = 0;
int l = 1, r = n;
while (l <= r) {
while (l <= r && b[l] == 0) {
l++;
}
while (l <= r && b[r] == p) {
r--;
}
if (r == l) {
ssum += min(b[l], p - b[l]);
break;
}
if (l > r) break;
ssum += b[l];
ll t = b[l];
b[l] = 0;
while (l <= r && t > 0) {
if ( b[r] + t >= p ) {
t -= (p - b[r]);
b[r] = p;
r--;
} else {
b[r] += t;
t = 0;
break;
}
}
}
if (ssum <= k) {
ans = max(ans, p);
}
}
signed main() {
cin >> n >> k;
for (ll i = 1; i <= n; i++) {
cin >> a[i];
sum += a[i];
}
ans = -1;
check(sum);
for (ll i = 1; i * i <= sum; i++) {
if (sum % i == 0) {
check(i);
check(sum / i);
}
}
cout << ans << endl;
return 0;
}
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Browser-use 详细介绍&使用文档
· 软件产品开发中常见的10个问题及处理方法
· Vite CVE-2025-30208 安全漏洞