Codeforces Round #601 (Div. 2)E(寻找质因子,DP)

先分解质因数,对于当前a[i],假设当前的质因数为x,这个位置要满足能被k整除,有两个可能,要么是它向后一个转移x%k个,要么是后一个向它转移k-x%k个。

对于每一个a[i]满足后,因为只会对下一个位置产生影响,所以下一个位置a[i+1]算上a[i]产生的影响,之后又是一个新的子问题(禁止套娃)。

对于每一个质因数x,对所有所有位置i求min(a[i],x-a[i])的和,取所有质因子i的求和的最小值作为答案。

 1 #define HAVE_STRUCT_TIMESPEC
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 long long a[1000007];
 5 int main(){
 6     ios::sync_with_stdio(false);
 7     cin.tie(NULL);
 8     cout.tie(NULL);
 9     long long n;
10     cin>>n;
11     long long sum=0;
12     for(long long i=1;i<=n;++i){
13         cin>>a[i];
14         sum+=a[i];
15     }
16     if(sum<=1){
17         cout<<-1;
18         return 0;
19     }
20     long long ans=1e18;
21     for(long long i=2;i*i<=sum;++i){
22         long long flag=0;
23         while(sum%i==0){
24             sum/=i;
25             flag=1;
26         }
27         if(flag){
28             long long pre=0,summ=0;
29             for(long long j=1;j<=n;++j){
30                 pre=(a[j]+pre)%i;
31                 summ+=min(pre,i-pre);
32             }
33             ans=min(ans,summ);
34         }
35     }
36     if(sum>1){
37         long long pre=0,summ=0;
38         for(long long j=1;j<=n;++j){
39             pre=(a[j]+pre)%sum;
40             summ+=min(pre,sum-pre);
41         }
42         ans=min(ans,summ);
43     }
44     cout<<ans;
45     return 0;
46 }

猜你喜欢

转载自www.cnblogs.com/ldudxy/p/11939327.html