HDU - 2588 GCD (欧拉函数)

我与影子孤独终老i 提交于 2019-11-28 15:34:50

原题链接
题意:
给你两个数 \(N,M\) 你要求出 符合条件 \(GCD(X,N)>=M,\space (1<=X<=M)\)\(X\)的个数
思路:
一开始没有往欧拉函数去想。总想着去筛出所有合适的因子然后统计个数,或者直接暴力for去枚举因子(肯定会TLE)
后面想到了一个互质关系(即是已知 \(GCD(X,N) = q\) \(X = q*a\)\(N=q*b\) \(则a,b必然互质\),然后我们就可以找到一个大于M的因子,开心的去找所有满足 小于 b 的互质个数即可。
然鹅...这不就是欧拉函数吗?所以最后我们在 用一个欧拉函数即可(离线打表和直接算都可以)

code:

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <cmath>
#define IOS ios::sync_with_stdio(0); cin.tie(0);
#define accept 0
#define mp make_pair
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int inf = 0x3f3f3f3f;
const int maxn = 1e3+7;
const int maxm = 1e6+7;
const int mod = 1e9+7;

int euler(int n){
    int i;
    int res = n,a = n;
    for(i = 2;i*i <= a; ++i){
        if(a%i == 0){
                res -= res/i; //p(n) = (p - p/p1)(1 - 1/p2)
                while(a%i == 0) a/=i;
        }   
    }
    if(a > 1) res -= res/a;//存在大于sqrt(a)的质因子
    return res;
}
int main() {
    int n, x, y, id;
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&x,&y);
        if(y==1) { printf("%d\n",x); continue; }
        ll sum = 0; 
        //单个因子大小不会超过平方根 
        for(int i = 1; i * i <= x; ++i) {
            if(x % i == 0){
                if(i >= y) sum += euler(x / i);
                if( (x / i) != i && (x / i) >= y)  sum +=  euler(i);
            } 
        }
        printf("%lld\n",sum);
    }
    return accept;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!