【题解】P2303 [SDOI2012] Longge 的问题
一句话题意
求\(\begin{aligned}\sum\limits_{i=1}^n \gcd(i, n)\end{aligned}\)
\(=\begin{aligned}\sum\limits_{d|n}d*\sum\limits_{i=1}^n[gcd(i,n)=d]\end{aligned}\)
\(=\begin{aligned}\sum\limits_{d|n}d*\sum\limits_{i=1}^\frac nd [gcd(i,\frac nd)=1]\end{aligned}\)
\(=\begin{aligned}\sum\limits_{d|n}d*\varphi(\frac nd)\end{aligned}\)
对于数据范围\(1\leq n\leq 2^{32}\),考虑在\(\sqrt n\)时间内筛出\(d\),用\(\varphi\)的定义求出\(\varphi\),就可以过了,时间复杂度为O(K\(\sqrt n\)),\(k\)为所筛\(d\)的个数
\(Code\)
#include<bits/stdc++.h>
#define LL long long
#define int long long
using namespace std;
/*Grievous Lady*/
template <typename T> void read(T & t){
t = 0;int f = 1;char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-')f =- 1;ch = getchar();}
do{t = t * 10 + ch - '0';ch = getchar();}while(ch >= '0' && ch <= '9');t *= f;
}
int n , ans , i;
const int kato = 1e7 + 1;
int prime[kato] , cnt;
bool ispri[kato];
inline void pri(int atri){
for(int i = 2;i <= atri;i ++){
if(!ispri[i]){
prime[++ cnt] = i;
}
for(int j = 1;j <= cnt && i * prime[j] <= atri;j ++){
ispri[i * prime[j]] = 1;
if(i % prime[j] == 0){
break;
}
}
}
}
inline int get_phi(int x){
int ans = x;
for(int i = 1;i <= cnt && prime[i] * prime[i] <= x;i ++){
if(x % prime[i]) continue;
ans = ans / prime[i] * (prime[i] - 1);
while(x % prime[i] == 0){
x /= prime[i];
}
}
if(x > 1){
ans = ans / x * (x - 1);
}
return ans;
}
inline int Ame_(){
read(n);
// cout << phi[1] << ' ' << phi[2];
pri(sqrt(n));
for(i = 1; i * i < n; i++){
// cout << i << '\n';
if(n % i == 0){
ans += i * get_phi(n / i) + (n / i) * get_phi(i);
}
}
if(i * i == n){
ans += i * get_phi(n / i);
}
printf("%lld" , ans);
return 0;
}
int Ame__ = Ame_();
signed main(){;}
呐,这份感情,什么时候可以传达呢