[关闭]
@Simon-Sun 2022-02-09T09:37:49.000000Z 字数 2285 阅读 276

数论

数论

约数个数

时间复杂度

~ 中,

int 范围内, = 1600

求约数的方法详见[例题]([P1072 NOIP2009 提高组] Hankson 的趣味题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn))

code

  1. #include <bits/stdc++.h>
  2. #define int long long
  3. using namespace std ;
  4. const int maxn = 5e4 + 10 ;
  5. int m , n , ans ;
  6. struct node//存每个质因子
  7. {
  8. int p , c ;//质因子,质因子的次数
  9. }factor[1605] ;//int 范围内最多的约数的个数
  10. int tot , cnt , num ; // 每个质因子的个数 , 约数的个数
  11. int prime[maxn >> 1] , di[maxn] ;
  12. bool is_prime[maxn] ;
  13. void erlu(int x)
  14. {
  15. for(int i = 2 ; i <= x ; i++)
  16. {
  17. if(! is_prime[i]) prime[++num] = i ;
  18. for(int j = 1 ; prime[j] <= x / i ; j++)
  19. {
  20. is_prime[prime[j] * i] = true ;
  21. if(! (i % prime[j])) break ;
  22. }
  23. }
  24. }
  25. int gcd(int a, int b)
  26. {
  27. return b ? gcd(b, a % b) : a;
  28. }
  29. void dfs(int u ,int p)
  30. {
  31. if(u > tot)
  32. {
  33. di[++cnt] = p ;
  34. return ;
  35. }
  36. for(int i = 1 ; i <= factor[u].c + 1 ; i++)
  37. {
  38. dfs(u + 1 ,p) ;
  39. p *= factor[u].p ;
  40. }
  41. }
  42. signed main()
  43. {
  44. int a, b , c , d ;
  45. cin >> n ;
  46. erlu(maxn - 1) ;
  47. while(n--)
  48. {
  49. cin >> a >> b >> c >> d ;//b1,c是d的约数
  50. int t = d ; tot = 0 ;
  51. for(int i = 1 ; prime[i] <= t / prime[i] ; i++ )
  52. {
  53. int p = prime[i] ;
  54. if(! (t % p))//是d的质因子
  55. {
  56. int c = 0 ;
  57. while(! (t % p)) t /= p , c++ ;
  58. factor[++tot] = {p , c} ;
  59. }
  60. }//试除法的原理实现
  61. if(t > 1)//循环除的情况下,说明t也是d的质因子
  62. factor[++tot] = {t , 1} ;
  63. cnt = 0 , ans = 0 ;
  64. dfs(1 , 1) ;//爆搜处理处所有的约数
  65. //cout <<cnt<<" " << num<<" " << tot<<" " ;
  66. for(int i = 1 ; i <= cnt ; i++ )
  67. {
  68. int x = di[i] ;
  69. if(gcd(a , x) == b && c * x / gcd(x , c) == d) ans++ ;
  70. }
  71. cout << ans ;
  72. puts("") ;
  73. }
  74. return 0 ;
  75. }

线性筛

法求欧拉函数

如果 的最小质因子

如果 不是 的最小质因子

如果 是质数

code

  1. void erlu(int n)
  2. {
  3. phi[1] = 1 ;
  4. for(int i = 2 ; i <= n ; i++)
  5. {
  6. if(! is_prime[i])
  7. {
  8. phi[i] = i - 1 ;
  9. prime[++cnt] = i ;
  10. }
  11. for(int j = 1 ; prime[j] <= n / i ; j++ )
  12. {
  13. is_prime[prime[j] * i] = true ;
  14. if( i % prime[j] == 0 )
  15. {
  16. phi[prime[j] * i] = phi[i] * prime[j] ;
  17. break ;
  18. }
  19. phi[prime[j] * i] = phi[i] * ( prime[j] - 1 ) ;
  20. }
  21. }
  22. }

以上性质在代码中均有体现

欧拉函数的其他性质

  1. 通式


    是根据唯一分解定理分解出来的 的质因子

  2. , 互质

  3. 为质数

欧拉定理和费马小定理

欧拉定理

若正整数 互质,则

是1~n中的一个质数

证明:

不是1~n中的一个质数,那么 = , 其中的一个因子,那么 有一个因子 b 和 a 。

费马小定理

欧拉定理的条件下,若 是一个质数,那么


证明:

用欧拉函数的引理把 替换掉就行了 。

应用:
费马小定理可以用来求乘法逆元
逆元:

则称 mod 意义下的逆元
例题
题意,求 mod 意义下的最小逆元。


首先利用费马小定理,构造处一组解

这里的 mod 意义下的最小逆元 , 即为所求
这里使用快速幂求解 ,模数即为
最后考虑无解的情况,根据费马小定理的使用条件,要保证 互质。所以对于 % = 的情况直接特判掉,输出

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注