luogu P2303 [SDOi2012]Longge的问题
Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N)。
gcd(i,N)不好求,那就转化一下,考虑 i/k 与 N/k 互质,(k为gcd(i,n)),那么就求一下1~N/k里有多少个数与N/k互质,即欧拉函数,里面每个数与N的gcd均为k,累加到答案中即可
考虑到N的范围较大,但其约数个数很少(1e8的约数个数为1e2)对每个约数直接O(√x)求欧拉函数即可,不用线筛,数组也开不下。
欧拉函数: fai(N)= N*∏(1- 1/p) ;
Code :
#include<iostream> #include<cstdio> #include<cmath> #define ll long long using namespace std; ll n,f[1000010],num,ans; int main(){ scanf("%lld",&n); for(int i=1;i<=sqrt(n);i++){ if(n%i==0){ f[++num]=i;if(n/i!=i) f[++num]=n/i; } } for(int i=1;i<=num;i++){ ll m=f[i],tmp=f[i]; for(int j=2;j<=sqrt(f[i]);j++){ if(f[i]%j==0){ m=m-m/j;while(f[i]%j==0) f[i]/=j; } } if(f[i]>1) m=m-m/f[i]; ans+=m*(n/tmp); } printf("%lld\n",ans);return 0; }