Send Boxes to Alice
Posted cadcadcad
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Send Boxes to Alice相关的知识,希望对你有一定的参考价值。
首先求出每一个位置的前缀和。
对答案进行复杂度为(sqrt{a[n]})的遍历,因为最后的答案不可能大于(sqrt{a[n]})
for(ll j=2;j*j<=a[n];++j) if(a[n]%j==0) { Try(j); while(a[n]%j==0) a[n]/=j; }
在
Try(j)
函数中,求的是当因子为(j)时的操作数量void Try(ll k) { ll temp=0; for(int i=1;i<n;++i) temp+=min(a[i]%k,k-a[i]%k); // tst(k,temp); best=min(best,temp); }
(temp+=min(a[i]\%k,k-a[i]\%k))的原因是在位置(i)上,如果不是(k)的倍数,那么,要么是将这个位置上的多出来的糖放到后面去,要么从后面拿糖过来。
取这两种方法的最小值,最后再求一个极值。
另外还要注意的一点是,无穷大要开得足够大,不然也会wa
代码:
// Created by CAD on 2019/11/23.
#include <bits/stdc++.h>
#define INF 0x7fffffffffffffff
#define ll long long
using namespace std;
const int maxn=1e6+5;
ll a[maxn];
ll best=INF,n;
void Try(ll k)
{
ll temp=0;
for(int i=1;i<n;++i)
temp+=min(a[i]%k,k-a[i]%k);
// tst(k,temp);
best=min(best,temp);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n;
for(int i=1;i<=n;++i)
cin>>a[i],a[i]+=a[i-1];
for(ll j=2;j*j<=a[n];++j)
if(a[n]%j==0)
{
Try(j);
while(a[n]%j==0)
a[n]/=j;
}
if(a[n]!=1) Try(a[n]);
cout<<(best==INF?-1:best)<<endl;
return 0;
}
以上是关于Send Boxes to Alice的主要内容,如果未能解决你的问题,请参考以下文章
E1. Send Boxes to Alice (Easy Version)
Codeforces Round #601 (Div. 2) E1 Send Boxes to Alice (Easy Version)
How to send patch to Linux upstream
Leetcode 1769. Minimum Number of Operations to Move All Balls to Each Box