计算最大公因数、最小公倍数
Euler 函数
Fermat定理
星期四的计算需要由中间过程,推算出3^3000%6 = 3 而 3^3%7 = 6
大数的素数分解
Miller-Rabin大数 素性检测实现
视频讲解链接(需要梯子)
https://www.youtube.com/watch?v=eC6YCv6sMzE
C++实现代码:
#include <iostream> #include <string> #include <cstring> #include <cstdio> #include <cstdlib> #include <time.h> #include <Windows.h> using namespace std; #ifndef ll #define ll long long #endif // rand 2 - e ll rand_Number(ll e) { return rand() % e + 1; } // a*b % c 快速乘 + mod ll mult_mod(ll a, ll b, ll c) { a %= c; b %= c; ll res = 0; while (b) { if (b & 1) { res += a; res %= c; } a <<= 1; //左移一位 相当于 a*=a if (a >= c) a %= c; b >>= 1; //b 下一位 } return res; } //a^u % num 快速幂 里面套快速乘 ll getRemainder(ll a, ll u, ll num) { ll cur = 1; ll nxt = a; while (u) { if (u & 1) { cur = mult_mod(cur, nxt, num); //cur *=nxt %num } nxt = mult_mod(nxt, nxt, num); //nxt *=nxt u = u >> 1; } return cur % num; } bool checkPrime(ll num) { int S = 20; //检测次数 if (num == 2) { return true; } if (num < 2 || num % 2 == 0) { return false; } ll u = num - 1; //肯定是偶数 while (u % 2 == 0) { u /= 2; } //这个时候 num = 2^(u*k) + 1 for (int i = 0; i < S; i++) { ll a = rand_Number(num - 1); //随机取一个小于num的数做检测 作为底数a^u % num ll x = getRemainder(a, u, num); //a^u % num ll x_1; ll tu = u; while (tu < num) { x_1 = mult_mod(x, x, num); //x=a^u x*x=a^2u x*x % num if (x_1 == 1 && x != 1 && x != num - 1) { //如果x_1==1 要满足 上一个x 是 1 or num-1 才没有非平凡根 //如果出现根不是 1 or num-1 那么就存在非平凡根 那num就是和数 return false; } if (x_1 == 1 && (x == 1 || x == num - 1)) { //已经出现1 后面再平方没意义 return true; } x = x_1; tu *= 2; //继续平方 算 a^2u a^4u a^8u } if (x != 1) { return false; } } return true; } int main() { ll n; scanf("%lld", &n); DWORD t1, t2; t1 = GetTickCount(); if (checkPrime(n)) { cout << "Yes" << endl; } else { cout << "No" << endl; } t2 = GetTickCount(); printf("Use Time:%f ", (t2 - t1) * 1.0 / 1000); return 0; }