0%

P2303 [SDOI2012] Longge 的问题

【题解】P2303 [SDOI2012] Longge 的问题

题目链接

求 $\displaystyle\sum_{i=1}^n \gcd(i,n)$

将这个柿子展开变复杂,得到

因为仅有 $d\mid n$ 且 $d \mid i$ 的时候可能会累加 $d$ ,则有效的 $i$ 一定是 $d$ 的倍数,即 $i = kd$

那么原式就可以化为

在这个柿子中,$d$ 是常量,将其提出来,并将 $kd\leq n$ 移项得 $k \leq \dfrac{n}{d}$ 得到

艾弗森括号里面的也能同时除个 $d$ 得到 $\displaystyle\sum_{d\mid n}d\sum_k^{\frac{n}{d}}[\gcd(k,\dfrac{n}{d})=1]$

由于 $\displaystyle\varphi(n)=\sum_{i=1}^{n}[\gcd(i,n)]$

所以原式就化成了 $\displaystyle\sum_{d\mid n}d\times \varphi(\dfrac{n}{d})$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

ll getPhi(ll n){
ll res = n;
for(ll i = 2;i*i<=n;i++){
if(n % i == 0) res = res / i * (i - 1);
while(n % i == 0) n /= i;
}
if(n > 1) res = res / n * (n - 1);
return res;
}

ll N;

int main(){
scanf("%lld",&N);
ll res = 0;
ll i = 1;
for(;i*i<N;i++){
if(N % i == 0) res += i * getPhi(N / i) + (N / i) * getPhi(i);
}
if(i * i == N) res += i * getPhi(i);
printf("%ll\n",res);
return 0;
}