题目链接
题意:给你n个数,至少选择一个,然后选择的数的gcd和是多少,两个选择不同,当且仅当有一个数的位置是不同的
dp[i][j]:表示前i个数选择出来gcd是j的种类数,gcd要提前算好,否者TLE
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define cl(a,b) memset(a,b,sizeof(a))
#define gcd __gcd
const int maxn = 1005;
const int inf = 1<<28;
const int mod = 100000007;
int a[maxn];
LL dp[maxn][maxn];//dp[i][j]:表示前i个数,gcd为j的种类数
int g[maxn][maxn];
int main(){
for(int i=0;i<maxn;i++)for(int j=0;j<maxn;j++)g[i][j]=gcd(i,j);
int T;scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
cl(dp,0);
dp[0][0]=1;
for(int i=0;i<n;i++){
for(int j=0;j<=1000;j++){
dp[i+1][j]=(dp[i+1][j]+dp[i][j])%mod;//不选
dp[i+1][g[a[i]][j]]=(dp[i+1][g[a[i]][j]]+dp[i][j])%mod;//选择
}
}
LL ans=0;
for(int i=1;i<=1000;i++)ans=(ans+dp[n][i]*i)%mod;
printf("%lld\n",ans);
}
return 0;
}