Mlxa

TEAMBOOK Ро-алгоритм Полларда

Nov 1st, 2019
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.08 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 isPrime(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. long pollard(long n, long x0, int iter) {
  77.     long a = x0, b = x0;
  78.     while (iter--) {
  79.         a = f(a, n);
  80.         b = f(f(b, n), n);
  81.         long d = __gcd(abs(a - b), n);
  82.         if (1 < d && d < n) {
  83.             return d;
  84.         }
  85.     }
  86.     return n;
  87. }
  88.  
  89. long pollard(long n) {
  90.     if (isPrime(n)) {
  91.         return n;
  92.     }
  93.     for (long d = 2, e = min(1000000LL, n); d < e; ++d) {
  94.         if (n % d == 0) {
  95.             return d;
  96.         }
  97.     }
  98.     mt19937 rnd;
  99.     uniform_int_distribution<long> randint(0, n - 1);
  100.     while (1) {
  101.         long x0 = randint(rnd);
  102.         long d = pollard(n, x0, 100000);
  103.         if (d != n) {
  104.             return d;
  105.         }
  106.     }
  107.     return n;
  108. }
  109.  
  110. vector<long> divisors(long n) {
  111.     if (n < 2) {
  112.         return {};
  113.     }
  114.     vector<long> st = {n};
  115.     vector<long> ans;
  116.     while (st.size()) {
  117.         n = st.back();
  118.         st.pop_back();
  119.         long d = pollard(n);
  120.         if (d == n) {
  121.             ans.push_back(d);
  122.         } else {
  123.             st.push_back(d);
  124.             st.push_back(n / d);
  125.         }
  126.     }
  127.     sort(all(ans));
  128.     return ans;
  129. }
  130.  
  131. ostream &operator<<(ostream &out, __int128 i) {
  132.     string s;
  133.     while (s.empty() || i) {
  134.         s += '0' + i % 10;
  135.         i /= 10;
  136.     }
  137.     reverse(all(s));
  138.     return out << s;
  139. }
  140.  
  141. __int128 geomPr(__int128 x, int c) {
  142.     ++c;
  143.     __int128 y = 1;
  144.     while (c--) {
  145.         y *= x;
  146.     }
  147.     return (y - 1) / (x - 1);
  148. }
  149.  
  150. void solve() {
  151.     long n;
  152.     cin >> n;
  153.     vector<long> d = divisors(n);
  154.     long phi = n;
  155.     long last = -1;
  156.     for (long x : d) {
  157.         if (x == last) {
  158.             continue;
  159.         }
  160.         last = x;
  161.         phi -= phi / x;
  162.     }
  163.     last = -1;
  164.     long cnt = 0;
  165.     long df = 1;
  166.     __int128 ds = 1;
  167.     for (long x : d) {
  168.         if (x == last) {
  169.             ++cnt;
  170.         } else {
  171.             ds *= geomPr(last, cnt);
  172.             df *= cnt + 1;
  173.             last = x;
  174.             cnt = 1;
  175.         }
  176.     }
  177.     ds *= geomPr(last, cnt);
  178.     df *= cnt + 1;
  179.     cout << phi << " " << df << " " << ds << "\n";
  180. }
  181.  
  182. int main() {
  183. #ifdef LC
  184.     assert(freopen("input.txt", "r", stdin));
  185. #else
  186. #endif
  187.     ios::sync_with_stdio(0);
  188.     cin.tie(0);
  189.     int t;
  190.     cin >> t;
  191.     while (t--) {
  192.         solve();
  193.     }  
  194.     return 0;
  195. }
Add Comment
Please, Sign In to add comment