题目大意:
求$displaystyle{sum_{1leq i<jleq n}}gcd(i,j)$的值。
思路:
由于数据水,可以直接用动态规划做。
用$f_k$表示在n以内以$k$为$gcd$的整数对个数,那么可以得到状态转移方程:
$f_i=lfloorfrac{n}{i}
floor-displaystyle{sum_{j=2}^{lfloorfrac{n}{i}
floor}}f_{ij}$
因为要减去$gcd(d,d)=d$的和$gcd(i,j)=gcd(j,i)$重复的,答案为:
$frac{displaystyle{sum_{i=1}^n}f_i-frac{n imes n+1}{2}}{2}$
1 #include<cstdio> 2 const long long N=2000001; 3 long long f[N]={0}; 4 inline long long sqr(const long long x) { 5 return x*x; 6 } 7 int main() { 8 long long n; 9 scanf("%lld",&n); 10 long long ans=0; 11 for(long long i=n;i;i--) { 12 f[i]=sqr(n/i); 13 for(long long j=2;j<=n/i;j++) { 14 f[i]-=f[i*j]; 15 } 16 ans+=f[i]*i; 17 } 18 printf("%lld ",(ans-n*(n+1)/2)/2); 19 return 0; 20 }