hdu2588 GCD(欧拉函数)

题意
给你 n , m n,m ,然后让你求解 x x ,有 1 < = x < = n 1<=x<=n ,使得 g c d ( x , n ) > = m gcd(x,n)>=m 成立的解的数目。
思路:
思路不是很好想,看别人题解后才做出来。
毫无疑问的是 g c d ( n , x ) gcd(n,x) 肯定是n的因子,假设 g c d ( n , x ) = a gcd(n,x)=a ,那么肯定有 g c d ( n / a , x / a ) = 1 gcd(n/a,x/a)=1 ,即 n a x a \dfrac{n}{a}与\dfrac{x}{a} 互质,因为 x < = n x<=n ,所以必有 n a > = x a \dfrac{n}{a}>=\dfrac{x}{a} ,且互质,根据欧拉函数的定义,我们要求解的数目,即是求 φ ( n a ) φ(\dfrac{n}{a}) 的和,其中a为 大于等于m的因子。
A C   C o d e : AC \ Code:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<map>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N =  2e6 + 10;
ll fac[N];
int tot ;
ll phi(ll n){
    ll ans = n;
    for(ll i = 2;i <= sqrt(n);++i){
        if(n % i == 0){
            ans = ans / i * (i - 1);
            while(n % i == 0) n /= i;
        }
    }
    if(n > 1) ans = ans /n *(n - 1);
    return ans;
}
int main(){
    ll n,m;
    int t;
    cin>>t;
    while(t--){
        tot = 0;
        cin >> n >> m;
        for(ll i = 1;i <= sqrt(n);++i){//找n的因数
            if(n % i == 0){
                fac[++tot] = i;
                if(n/ i != i) fac[++tot] = n / i;
            }
        }
        sort(fac + 1,fac + tot + 1);
        int idx = lower_bound(fac + 1,fac + tot + 1,m) - fac;//找到大于等于m的位置
        ll sum = 0;
        for(int i = idx; i <= tot;++i){
            sum += phi(n / fac[i]);
        }
        cout<<sum<<endl;
    }
}
发布了632 篇原创文章 · 获赞 27 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_43408238/article/details/103990560