链接:https://codeforces.com/contest/1614/problem/D1
难度:*2100
标签:dp
number theory
题意
给你 n n n 个数,求出 ∑ i = 1 n gcd ( a 1 , a 2 , a 3 , . . . , a i ) \displaystyle \sum_{i=1}^{n} \gcd(a_1,a_2,a_3, \ ... \ , a_i) i=1∑ngcd(a1,a2,a3, ... ,ai)
题解
定义 c n t [ i ] cnt[i] cnt[i]:数组 a a a 中是 i i i 的倍数的元素个数
定义 d p [ i ] dp[i] dp[i]:表示目前 gcd = i \gcd = i gcd=i,前缀 gcd \gcd gcd 和的最大值。
转移:
d
p
[
i
]
=
max
j
m
o
d
i
=
0
,
i
≠
j
(
d
p
[
i
]
,
d
p
[
j
]
+
i
∗
(
c
n
t
[
j
]
−
c
n
t
[
i
]
)
)
dp[i]=\displaystyle \mathop{\max}_{j \bmod i =0 ,\ i \ne j} (dp[i],dp[j]+i*(cnt[j]-cnt[i]))
dp[i]=maxjmodi=0, i=j(dp[i],dp[j]+i∗(cnt[j]−cnt[i]))
C++ 代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=5e6+5;
int n;
int v[maxn];
int cnt[maxn];
int dp[maxn];
signed main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>v[i];
cnt[v[i]]++;
}
for(int i=1;i<maxn;i++){
for(int j=2*i;j<maxn;j+=i){
cnt[i]+=cnt[j];
}
}
int mx=0;
for(int i=maxn-1;i>=1;i--){
dp[i]=i*cnt[i];
for(int j=2*i;j<maxn;j+=i){
dp[i]=max(dp[i],dp[j]+i*(cnt[i]-cnt[j]));
}
mx=max(dp[i],mx);
}
cout<<mx<<endl;
return 0;
}