NYOJ 998&& HDOJ2588 GCD (欧拉函数)

链接:click here

题意: 给你一个数N,使得在1~N之间能够找到x使得x满足gcd( x ,  N  ) >= M求解gcd(x,N)的和

解题思路:直接枚举1~N的值,判断满足条件则ans++,数据量太大,用常规方法做是行不通的。
这题其实考查欧拉函数,可以这样想:先找出N的约数x,
并且gcd(x,N)>= M,结果为所有N/x的欧拉函数之和。

不妨令 N = p * d,x = q * d,那么如果 gcd(x,N) = d,一定有 p,q 互质,又有 x <= N,则 q <= p,而统计这样的 q 的个数正好对应欧拉函数的作用。

所以结果就是枚举所有满足 d >= m 的 d,将相应的 phi(p) 求和。

 代码:

#include <bits/stdc++.h>
using namespace std;
int eular(int n)
{
    int res=1;
    for(int i=2; i*i<=n; i++)
    {
        if(n%i==0)
        {
            n/=i,res*=i-1;
            while(n%i==0)
            {
                n/=i,res*=i;
            }
        }
    }
    if(n!=1) res*=n-1;
    return res;
}
int gcd(int a,int b) {return b==0?a:gcd(b,a%b);}
int main()
{
    int t,n,m;
    t=shuru();
    while(t--)
    {
        n=shuru();
        m=shuru();
        int sum=0;
        for(int i=1;i*i<=n;i++)
        {
            if(n%i) continue;
            //if(n%i==0)//约数
                if(i>=m) sum+=eular(n/i);
                if(i*i!=n&&n/i>=m) sum+=eular(i);
        }
       printf("%d\n",sum);
    }
    return 0;
}


你可能感兴趣的:(数论,ACM)