1. 程式人生 > >[洛谷1390]公約數的和

[洛谷1390]公約數的和

由於 個數 直接 display lin print logs for tdi

題目大意:

求$\displaystyle{\sum_{1\leq i<j\leq n}}gcd(i,j)$的值。

思路:

由於數據水,可以直接用動態規劃做。
用$f_k$表示在n以內以$k$為$gcd$的整數對個數,那麽可以得到狀態轉移方程:
$f_i=\lfloor\frac{n}{i}\rfloor-\displaystyle{\sum_{j=2}^{\lfloor\frac{n}{i}\rfloor}}f_{ij}$
因為要減去$gcd(d,d)=d$的和$gcd(i,j)=gcd(j,i)$重復的,答案為:
$\frac{\displaystyle{\sum_{i=1}^n}f_i-\frac{n\times 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\n",(ans-n*(n+1)/2)/2); 19 return 0; 20 }

[洛谷1390]公約數的和