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;
}

 

posted @ 2019-10-12 14:17  dzzx_Syh  阅读(112)  评论(0编辑  收藏  举报