版权声明:本文为博主原创文章,欢迎转载。 https://blog.csdn.net/Smiler_/article/details/80092294
- 题意:给你一串数字,让人找出所有的字串(可不连续),使得该串的gcd()>1,如果该串中有k个数,求出所有满足该条件的字串的k*gcd()的和。
- 思路:假设某一串的gcd()的长度为n,gcd()为i,则该字串的和为,经过化简可以得到,这个时候会有重复的,我们要减去多加的,这个时候多加的比如这样:2,4 ,8,我们把(4,8)的组合放在gcd()为2的位置了,而实际gcd(4,8)=4,所以我们要减去相同的。
-
#include <iostream> #include <algorithm> #include <vector> #include <cmath> #include <cstring> using namespace std; const int mod=1000000007; const int maxn=1000000+10; long long dp[maxn]; long long a[maxn]; int num[1000010]; long long b[maxn]; int main() { int n; cin>>n; int maxx=0; dp[0]=1; memset(num,0,sizeof(num)); for(int i=1; i<=n; i++) { int x; cin>>x; maxx=max(maxx,x); dp[i]=(2*dp[i-1])%mod; num[x]++; } long long ans=0; long long sum=0; for(int i=maxx; i>=2; i--) { int temp=0; sum=0; for(int j=i; j<=maxx; j+=i) { temp+=num[j]; } if(temp==0) continue; sum=((long long)temp*dp[temp-1])%mod; for(int j=i*2; j<=maxn; j+=i) { sum=(sum-b[j]+mod)%mod; } b[i]=sum; ans=(ans+((long long)i*sum)%mod)%mod; } cout<<ans%mod<<endl; return 0; }