欧拉函数_HDU 2588

题目意思

题目中给出我们我们两个数字n,m,要求我们寻找x(x<=n) 并且gcd(x,n) >= m 

题目解析

实质上我们可以寻找n的因子x,那么我们就可以确定gcd(n,x) = x

要求我们的x满足:gcd(n,x) = x >= m

设y = n/x ,那么我们就可以寻找y的质因子pi

那么pi*y一定满足下面条件:

gcd(pi*y,n) = x >= m

那么我们的问题就可以转变为求解y的所有质因子个数,即y的欧拉函数

但是这里会出现一个问题,如果我们直接遍历n,寻找n的因子的话,这样也会时间超限,然后我们会发现,如果找到了一个n的因子x,那么n/x一定也是n的因子,这样的话,我们可以直接遍历x*x <= n的情况即可

当x >= m  ,  ans += Euler(n/x);

当n/x >= m  ,ans += Euler(x);             //满足另一个因子是大于m的,那么答案加Euler(n/(n/x))

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <map>
#include <queue>
#include <algorithm>
#define INF 0x3f3f3f3f
#define ll long long
using namespace std;

int Euler(int n)
{
    if(n == 1) return 1;
    int ans = n;
    for(int i = 2;i * i <= n;i ++)
    {
        if(n % i == 0)
        {
            ans -= ans/i;
            while(n % i == 0) n /= i;
        }
    }
    if(n != 1)
        ans -= ans/n;
    return ans;
}
int solve(int n,int m)
{
    int ans = 0;
    for(int i = 1;i * i <= n;i ++)
    {
        if(n % i ) continue;  
        if(i >= m && i * i != n)
            ans += Euler(n/i);  
        if(n/i >= m)
            ans += Euler(i);
    }
    return ans;
}
int main()
{
    int T;
    int n,m;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        printf("%d\n",solve(n,m));
    }
    return 0;
}

参考博客

https://blog.csdn.net/acdreamers/article/details/8544781

猜你喜欢

转载自blog.csdn.net/li1615882553/article/details/80579495