• 【数学知识】—— 快速幂 / 扩展欧几里得算法



    互质与欧拉函数

    定义

            \forall a,b\epsilon \mathbb{N},若gcd(a,b)=1,则称 a,b 互质

            对于三个数或更多数的情况,我们把 gcd(a,b,c)=1 的情况称为 a, b, c 互质。

    把 \gcd (a,b)=\gcd(a,c)=\gcd(b,c)=1 称为 a,b,c 两两互质。后者显然是一个更强的条件

    欧拉函数

            1 ~ N 中与 N 互质的数的个数被称为欧拉函数,记为 \varphi (N) 

            若在算数基本定理中,N=p_1^{c_1}p_2^{c_2}...p_m^{c_m},则:

            \large \varphi (N)=N*\frac{p_1-1}{p_1}\frac{p_2-1}{p_2}*...*\frac{p_m-m}{p_m}=N*\prod_{p|N}^{}(1-\frac{1}{p}) 

     证明:

            设 p 是 N 的质因子,1 ~ N 中 p 的倍数有 p, 2p, 3p, ..., (N/P) * p,N/p 个。 

    同理,若 q 也是 N 的质因子,则 1 ~ N 中 q 的倍数有 N/q 个。如果我们把这 N/p + N/q 个数去掉,那么 p * q 的倍数就被排除了两次,需要再加回来一次。因此,1 ~ N 中不与 N 含有共同质因子的 p 或 q 的个数为:

    \large N - \frac{N}{p} - \frac{N}{q} + \frac{N}{pq} = N*(1-\frac{1}{p}-\frac{1}{q}+\frac{1}{pq})=N(1-\frac{1}{p})(1-\frac{1}{q})

             实际上,上述思想被称为容斥原理。类似的,我们可以在 N 的全部质因子上使用容斥原理,就能得到 1 ~ N  中不与 N 含有共同质因子的数的个数,也是就是与 N 互质的个数

    证毕。


    AcWing 873. 欧拉函数  

    输入样例:

    1. 3
    2. 3
    3. 6
    4. 8

    输出样例:

    1. 2
    2. 2
    3. 4

    1. #include
    2. #include
    3. using namespace std;
    4. int main()
    5. {
    6. int n;
    7. cin >> n;
    8. while(n -- )
    9. {
    10. int a; cin >> a;
    11. int res = a;
    12. for(int i = 2; i <= a / i; i ++ )
    13. if(a % i == 0)
    14. {
    15. res = res / i * (i - 1);
    16. while(a % i == 0) a /= i;
    17. }
    18. if(a > 1) res = res / a * (a - 1);
    19. cout << res << endl;
    20. }
    21. return 0;
    22. }

    AcWing 874. 筛法求欧拉函数 

    输入样例:

    6
    

    输出样例:

    12

    线性筛的算法回顾

    1. for(int i = 2; i <= n; i ++ )
    2. {
    3. if(!st[i])
    4. {
    5. primes[cnt ++ ] = i;
    6. }
    7. for(int j = 0; primes[j] <= n / i; j ++ )
    8. {
    9. st[primes[j] * i] = true;
    10. if(i % primes[j] == 0) break;
    11. }
    12. }

    https://www.acwing.com/solution/content/28507/


    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. const int N = 1000010;
    6. typedef long long LL;
    7. int primes[N], cnt;
    8. int phi[N];
    9. bool st[N];
    10. LL get_eulers(int n)
    11. {
    12. phi[1] = 1;
    13. for(int i = 2; i <= n; i ++ )
    14. {
    15. if(!st[i])
    16. {
    17. primes[cnt ++ ] = i;
    18. phi[i] = i - 1;
    19. }
    20. for(int j = 0; primes[j] <= n / i; j ++ )
    21. {
    22. st[primes[j] * i] = true;
    23. if(i % primes[j] == 0)
    24. {
    25. phi[primes[j] * i] = phi[i] * primes[j];
    26. break;
    27. }
    28. phi[primes[j] * i] = phi[i] * (primes[j] - 1);
    29. }
    30. }
    31. LL res = 0;
    32. for(int i = 1; i <= n; i ++ ) res += phi[i];
    33. return res;
    34. }
    35. int main()
    36. {
    37. int n;
    38. cin >> n;
    39. cout << get_eulers(n) << endl;
    40. return 0;
    41. }

    欧拉定理

    a 与 n 互质,则 \large a^{\varphi (n)} \equiv 1\;(mod \;n)


     AcWing 875. 快速幂

     

    输入样例:

    1. 2
    2. 3 2 5
    3. 4 3 9

    输出样例:

    1. 4
    2. 1

    1. #include
    2. #include
    3. using namespace std;
    4. typedef long long LL;
    5. int n;
    6. int qmi(int a, int k, int p)
    7. {
    8. int res = 1;
    9. while(k)
    10. {
    11. if(k & 1) res = (LL)res * a % p;
    12. a = (LL)a * a % p;
    13. k >>= 1;
    14. }
    15. return res;
    16. }
    17. int main()
    18. {
    19. cin >> n;
    20. while(n -- )
    21. {
    22. int a, k, p;
    23. scanf("%d%d%d", &a, &k, &p);
    24. printf("%d\n", qmi(a, k, p));
    25. }
    26. return 0;
    27. }

    AcWing 876. 快速幂求逆元

     

    输入样例:

    1. 3
    2. 4 3
    3. 8 5
    4. 6 3

    输出样例:

    1. 1
    2. 2
    3. impossible

     


    1. #include
    2. #include
    3. using namespace std;
    4. typedef long long LL;
    5. LL qmi(int a, int b, int p)
    6. {
    7. LL res = 1;
    8. while(b)
    9. {
    10. if(b & 1) res = res * a % p;
    11. a = a * (LL)a % p;
    12. b >>= 1;
    13. }
    14. return res;
    15. }
    16. int main()
    17. {
    18. int n;
    19. cin >> n;
    20. while(n --)
    21. {
    22. int a, p;
    23. cin >> a >> p;
    24. int res = qmi(a, p - 2,p);
    25. if(a % p) cout << res << endl;
    26. else puts("impossible");
    27. }
    28. return 0;
    29. }

    扩展欧几里得算法

    裴蜀定理

            对于任意的整数 a,b,一定存在一对整数非0 x,y,满足  \large ax+by=\gcd(a,b)


    AcWing 877. 扩展欧几里得算法        

    输入样例:

    1. 2
    2. 4 6
    3. 8 18

    输出样例:

    1. -1 1
    2. -2 1

    扩展欧几里得 

    对于求解更一般的方程 ax+by=c 

    应用: 求解一次同余方程 ax≡b(modm) 

    AcWing 877. 扩展欧几里得算法 - AcWing 


    1. #include
    2. using namespace std;
    3. int exgcd(int a, int b, int& x, int& y)
    4. {
    5. if(!b)
    6. {
    7. x = 1, y = 0;
    8. return a;
    9. }
    10. int d = exgcd(b, a % b, y, x);
    11. y -= a / b * x;
    12. return d;
    13. }
    14. int main()
    15. {
    16. int n; cin >> n;
    17. while(n -- )
    18. {
    19. int a, b, x, y;
    20. scanf("%d%d", &a, &b);
    21. exgcd(a, b, x, y);
    22. printf("%d %d\n", x, y);
    23. }
    24. return 0;
    25. }

    AcWing 878. 线性同余方程 

    输入样例:

    1. 2
    2. 2 3 6
    3. 4 3 5

    输出样例:

    1. impossible
    2. -3

     

     


    1. #include
    2. using namespace std;
    3. typedef long long LL;
    4. int exgcd(int a,int b,int &x,int &y)
    5. {
    6. if(!b)
    7. {
    8. x = 1,y = 0;
    9. return a;
    10. }
    11. int d = exgcd(b,a % b,y,x);
    12. y -= a / b * x;
    13. return d;
    14. }
    15. int main()
    16. {
    17. int n;
    18. cin >> n;
    19. while(n --)
    20. {
    21. int a,b,m;
    22. scanf("%d%d%d",&a,&b,&m);
    23. int x,y;
    24. int d = exgcd(a,m,x,y);
    25. if(b % d) puts("impossible");
    26. else printf("%d\n",(LL)x * (b / d) % m);
    27. }
    28. return 0;
    29. }

  • 相关阅读:
    漫谈测试成长之探索——测试汇报
    CMAKE小知识
    部署高校房屋管理系统可以实现哪些目标?
    【DS】树和二叉树的理论知识梳理
    Leetcode 662. 二叉树最大宽度
    基于51单片机的贪吃蛇游戏设计
    【JS】JavaScript入门笔记第五弹之预解析、对象~
    关于本地项目连接git远程仓库以及git设置ignore文件
    ThingsBoard如何自定义tcp-transport
    关于Redis的问题探讨(二):Range方法返回的对象是LinkeHashMap以及转换办法
  • 原文地址:https://blog.csdn.net/forever_bryant/article/details/126222314