@Simon-Sun
2022-02-09T09:37:49.000000Z
字数 2285
阅读 276
~ 中,
#include <bits/stdc++.h>#define int long longusing namespace std ;const int maxn = 5e4 + 10 ;int m , n , ans ;struct node//存每个质因子{int p , c ;//质因子,质因子的次数}factor[1605] ;//int 范围内最多的约数的个数int tot , cnt , num ; // 每个质因子的个数 , 约数的个数int prime[maxn >> 1] , di[maxn] ;bool is_prime[maxn] ;void erlu(int x){for(int i = 2 ; i <= x ; i++){if(! is_prime[i]) prime[++num] = i ;for(int j = 1 ; prime[j] <= x / i ; j++){is_prime[prime[j] * i] = true ;if(! (i % prime[j])) break ;}}}int gcd(int a, int b){return b ? gcd(b, a % b) : a;}void dfs(int u ,int p){if(u > tot){di[++cnt] = p ;return ;}for(int i = 1 ; i <= factor[u].c + 1 ; i++){dfs(u + 1 ,p) ;p *= factor[u].p ;}}signed main(){int a, b , c , d ;cin >> n ;erlu(maxn - 1) ;while(n--){cin >> a >> b >> c >> d ;//b1,c是d的约数int t = d ; tot = 0 ;for(int i = 1 ; prime[i] <= t / prime[i] ; i++ ){int p = prime[i] ;if(! (t % p))//是d的质因子{int c = 0 ;while(! (t % p)) t /= p , c++ ;factor[++tot] = {p , c} ;}}//试除法的原理实现if(t > 1)//循环除的情况下,说明t也是d的质因子factor[++tot] = {t , 1} ;cnt = 0 , ans = 0 ;dfs(1 , 1) ;//爆搜处理处所有的约数//cout <<cnt<<" " << num<<" " << tot<<" " ;for(int i = 1 ; i <= cnt ; i++ ){int x = di[i] ;if(gcd(a , x) == b && c * x / gcd(x , c) == d) ans++ ;}cout << ans ;puts("") ;}return 0 ;}
void erlu(int n){phi[1] = 1 ;for(int i = 2 ; i <= n ; i++){if(! is_prime[i]){phi[i] = i - 1 ;prime[++cnt] = i ;}for(int j = 1 ; prime[j] <= n / i ; j++ ){is_prime[prime[j] * i] = true ;if( i % prime[j] == 0 ){phi[prime[j] * i] = phi[i] * prime[j] ;break ;}phi[prime[j] * i] = phi[i] * ( prime[j] - 1 ) ;}}}
通式
若 , 互质
为质数
若正整数 和 互质,则
是1~n中的一个质数
证明:
若 不是1~n中的一个质数,那么 = , 其中是的一个因子,那么 即 和 有一个因子 b 和 a 。
欧拉定理的条件下,若 是一个质数,那么
用欧拉函数的引理把 替换掉就行了 。
应用:
费马小定理可以用来求乘法逆元
逆元:
若
则称 是 在mod 意义下的逆元
例题
题意,求 在 mod 意义下的最小逆元。