HDU - 2588 GCD (欧拉函数)

匿名 (未验证) 提交于 2019-12-02 23:55:01

原题链接
题意:
给你两个数 \(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; }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!