Mlxa

TEAMBOOK Миллер-Рабин

Nov 1st, 2019
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.41 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using ld = long double;
  3. #define long long long
  4. #define all(x) x.begin(), x.end()
  5. using namespace std;
  6.  
  7. long f(__int128 x, long n) {
  8.     return (long)((x * x + 1) % n);
  9. }
  10.  
  11. __int128 powerMod(__int128 a, long p, __int128 m) {
  12.     a %= m;
  13.     __int128 x = 1;
  14.     for (; p > 0; p >>= 1) {
  15.         if (p & 1) {
  16.             x *= a;
  17.             x %= m;
  18.         }
  19.         a *= a;
  20.         a %= m;
  21.     }
  22.     return x;
  23. }
  24.  
  25. bool millerRabin(long n) {
  26.     if (n <= 2) {
  27.         return n == 2;
  28.     }
  29.     if (n % 2 == 0) {
  30.         return false;
  31.     }
  32.     if (n <= 40) {
  33.         for (int d = 2; d < n; ++d) {
  34.             if (n % d == 0) {
  35.                 return false;
  36.             }
  37.         }
  38.         return true;
  39.     }
  40.     long p = n - 1;
  41.     long q = p;
  42.     while (q % 2 == 0) {
  43.         q /= 2;
  44.     }
  45.     for (long a : {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}) {
  46.         __int128 e = powerMod(a, p, n);
  47.         if (e != 1) {
  48.             return false;
  49.         }
  50.         __int128 x = powerMod(a, q, n);
  51.         vector<__int128> arr;
  52.         while (x != e) {
  53.             arr.push_back(x);
  54.             x *= x;
  55.             x %= n;
  56.         }
  57.         bool have_1 = false;
  58.         bool trash  = false;
  59.         for (auto el : arr) {
  60.             if (el == n - 1) {
  61.                 have_1 = true;
  62.             }
  63.         }
  64.         for (auto el : arr) {
  65.             if (el != 1) {
  66.                 trash = true;
  67.             }
  68.         }
  69.         if (trash && !have_1) {
  70.             return false;
  71.         }
  72.     }
  73.     return true;
  74. }
  75.  
  76. bool stupidPrime(long n) {
  77.     if (n < 2) {
  78.         return false;
  79.     }
  80.     for (long d = 2; d * d <= n; ++d) {
  81.         if (n % d == 0) {
  82.             return false;
  83.         }
  84.     }
  85.     return true;
  86. }
  87.  
  88. long pollard(long n, long x0, int iter) {
  89.     long a = x0, b = x0;
  90.     while (iter--) {
  91.         a = f(a, n);
  92.         b = f(f(b, n), n);
  93.         long d = __gcd(abs(a - b), n);
  94.         if (1 < d && d < n) {
  95.             return d;
  96.         }
  97.     }
  98.     return n;
  99. }
  100.  
  101. long pollard(long n, int s, int x, int y) {
  102.     for (int d = 2; d <= s; ++d) {
  103.         if (n % d == 0) {
  104.             return d;
  105.         }
  106.     }
  107.     mt19937 rnd;
  108.     uniform_int_distribution<long> randint(0, n - 1);
  109.     while (x--) {
  110.         long x0 = randint(rnd);
  111.         long d = pollard(n, x0, y);
  112.         if (d != n) {
  113.             return d;
  114.         }
  115.     }
  116.     return n;
  117. }
  118.  
  119. int main() {
  120. #ifdef LC
  121.     assert(freopen("input.txt", "r", stdin));
  122. #else
  123.     assert(freopen("again.in", "r", stdin));
  124.     assert(freopen("again.out", "w", stdout));
  125. #endif
  126.     ios::sync_with_stdio(0);
  127.     cin.tie(0);
  128.    
  129.     long x;
  130.     cin >> x;
  131.     while (cin >> x) {
  132.         if (millerRabin(x)) {
  133.             cout << "YES\n";
  134.         } else {
  135.             cout << "NO\n";
  136.         }
  137.     }
  138.    
  139.     /*
  140.     for (long x = 1; x <= 1000000; ++x) {
  141.         if (stupidPrime(x) != millerRabin(x)) {
  142.             cout << x << " " << stupidPrime(x) << endl;
  143.         }
  144.     }
  145.     */
  146.     return 0;
  147. }
Add Comment
Please, Sign In to add comment