[Codeforces Round #601 (Div. 2)]E2. Send Boxes to Alice(Hard Version)

简化版https://blog.csdn.net/qq_33831360/article/details/103170669
就是数据变大了

优化:k不是sqrt枚举,因为因子nk(个一组)结果可能不比因子k(个一组)好,所以分解质因数枚举质因子k

枚举的方法:移动到点i后,积累了had<k个礼物,那么有两种选择,把这had个后移,或把k-had个前移。
计算过程模拟的是后移,但实际上,对于这k个礼物,前一部分后移,随着had变大,后一部分前移。是有一致性的,且后部分模拟后移只是为了计算需要前移多少。


#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
 
using namespace std;
#define int long long 
int n;
typedef long long LL;
LL a[1000003];
 
LL calc(int x) {
	LL ans = 0;
	LL had = 0;
    for (int i = 1; i <= n; i++) {
    	had = had+a[i];
		if (had > x) had %= x;
    	ans += min(had,x-had);
	}
	return ans;
}
 
main() {
	LL sum = 0;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		scanf("%I64d",&a[i]);
		sum += a[i];
	}
	if (sum <= 1) {
		puts("-1");
		return 0;
	} 
	LL ans = (LL)1e18;
	for (LL i = 2; i <= sqrt(sum); i++)
		if (sum % i == 0) {
			ans = min(ans,calc(i));
			while (sum%i == 0) sum /= i;
		}
	if (sum > 1) ans = min(ans,calc(sum));
    cout << ans;
	return 0;
}
 

猜你喜欢

转载自blog.csdn.net/qq_33831360/article/details/103173557