hdu2588 GCD(欧拉函数)

题意:求解小于n的数i且gcd(i,n)大于m的i的个数

分析:

对于所有小于n的最大公约数值一定是n的因子,所以,从这个方面下手找i为n的因子且i>m时求解车i的素数倍数且小于n的个数累加起来就好了。以为这个倍数最大为n/i所以求得n/i的欧拉函数值累加起来就好了。

代码如下:

#include <set>
#include <map>
#include <stack>
#include <queue>
#include <math.h>
#include <vector>
#include <string>
#include <utility>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;
long long euler(long long  n){ //返回euler(n)
     long long  res=n,a=n;
     for(long long  i=2;i*i<=a;i++){
         if(a%i==0){
             res=res/i*(i-1);//先进行除法是为了防止中间数据的溢出
             while(a%i==0) a/=i;
         }
     }
     if(a>1) res=res/a*(a-1);
     return res;
}
//欧拉函数值
long long a[1000010];
int main(){
    long long n,m;
    int t;
    cin>>t;
    while(t--){
        long long ans=0;
        scanf("%I64d%I64d",&n,&m);
        for(int i=1;i*i<=n;i++){//判断sqrt(n)就好
            if(n%i!=0)continue;
            if(i>=m&&i*i!=n){
                ans+=euler(n/i);
            }
            if(n/i>=m){
                ans+=euler(i);//一个是i,一个是n/i
            }
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


你可能感兴趣的:(数学,欧拉函数)