Tuesday, April 14, 2020

[Spoj] PUCMMT02 - Square-Free Product (Hard)

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : PUCMMT02 - Square-Free Product (Hard)
Source            : Spoj 
Category          : Number Theory
Algorithm         : Pollard Rho Prime Factorization
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2.    
  3. using namespace std;  
  4.    
  5. namespace Rho  // Implementation: s_h_shahin, du
  6. {  
  7.       mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());  
  8.    
  9.       const int MAXP = 1000010;  
  10.       const int BASE[] = {2, 450775, 1795265022, 9780504, 28178, 9375, 325};  
  11.    
  12.       long long seq[MAXP];  
  13.       int primes[MAXP];  
  14.       int spf[MAXP];  
  15.    
  16.       inline long long mod_add(long long x, long long y, long long m)  
  17.       {  
  18.             x += y;  
  19.             if (x >= m) x -= m;  
  20.             return x;  
  21.       }  
  22.       inline long long mod_mul(long long x, long long y, long long m)  
  23.       {  
  24.             long long res = x * y - (long long)((long double)x * y / m + 0.5) * m;  
  25.             return res < 0 ? res + m : res;  
  26.       }  
  27.       inline long long mod_pow(long long x, long long p, long long m)  
  28.       {  
  29.             long long res = 1 % m;  
  30.             for ( ; p; p >>= 1)  
  31.             {  
  32.                   if (p & 1) res = mod_mul(res, x, m);  
  33.                   x = mod_mul(x, x, m);  
  34.             }  
  35.             return res;  
  36.       }  
  37.       // O(k * logn * logn * logn), k = number of rounds performed  
  38.       inline bool miller_robin(long long n)  
  39.       {  
  40.             if (n <= 2 or (~n & 1)) return (n == 2);  
  41.             if (n < MAXP) return spf[n] == n;  
  42.             long long c;  
  43.             long long d;  
  44.             long long s = 0;  
  45.             long long r = n - 1;  
  46.             while (~r & 1)  
  47.             {  
  48.                   s++;  
  49.                   r >>= 1;  
  50.             }  
  51.             // each iteration is a round  
  52.             for (int i = 0; primes[i] < n and primes[i] < 32; i++)  
  53.             {  
  54.                   c = mod_pow(primes[i], r, n);  
  55.                   for (int j = 0; j < s; j++)  
  56.                   {  
  57.                         d = mod_mul(c, c, n);  
  58.                         if (d == 1 and c != 1 and c != (n - 1)) return false;  
  59.                         c = d;  
  60.                   }  
  61.                   if (c != 1) return false;  
  62.             }  
  63.             return true;  
  64.       }  
  65.       inline void sieve()  
  66.       {  
  67.             int cnt = 0;  
  68.             for (int i = 2; i < MAXP; i++)  
  69.             {  
  70.                   if (spf[i] == 0) primes[cnt++] = spf[i] = i;  
  71.                   for (int j = 0; 1LL * i * primes[j] < MAXP; j++)  
  72.                   {  
  73.                         spf[i * primes[j]] = primes[j];  
  74.                         if (spf[i] == spf[i * primes[j]]) break;  
  75.                   }  
  76.             }  
  77.       }  
  78.       // expected complexity O(n ^ 1/4)  
  79.       long long pollard_rho(long long n)  
  80.       {  
  81.             while (true)  
  82.             {  
  83.                   long long x = rand() % n;  
  84.                   long long y = x;  
  85.                   long long c = rand() % n;  
  86.                   long long u = 1;  
  87.                   long long v;  
  88.                   long long t = 0;  
  89.                   long long *px = seq;  
  90.                   long long *py = seq;  
  91.                   while (true)  
  92.                   {  
  93.                         *py++ = y = mod_add(mod_mul(y, y, n), c, n);  
  94.                         *py++ = y = mod_add(mod_mul(y, y, n), c, n);  
  95.                         if ((x = *px++) == y) break;  
  96.                         v = u;  
  97.                         u = mod_mul(u, abs(y - x), n);  
  98.                         if (u == 0) return __gcd(v, n);  
  99.                         if (++t == 32)  
  100.                         {  
  101.                               t = 0;  
  102.                               if ((u = __gcd(u, n)) > 1 and u < n) return u;  
  103.                         }  
  104.                   }  
  105.                   if (t and (u = __gcd(u, n)) > 1 and u < n) return u;  
  106.             }  
  107.       }  
  108.       vector <long long> factorize(long long n)  
  109.       {  
  110.             if (n == 1) return vector <long long> ();  
  111.             if (miller_robin(n)) return vector <long long> {n};  
  112.             vector <long long> lchild, rchild;  
  113.             while (n > 1 and n < MAXP)  
  114.             {  
  115.                   lchild.push_back(spf[n]);  
  116.                   n /= spf[n];  
  117.             }  
  118.             if (n >= MAXP)  
  119.             {  
  120.                   long long x = pollard_rho(n);  
  121.                   lchild = factorize(x);  
  122.                   rchild = factorize(n / x);  
  123.                   lchild.insert(lchild.end(), rchild.begin(), rchild.end());  
  124.             }  
  125.             sort(lchild.begin(), lchild.end());  
  126.             return lchild;  
  127.       }  
  128. }  
  129.    
  130. signed main()  
  131. {  
  132.       ios_base::sync_with_stdio(false);  
  133.       cin.tie(nullptr);  
  134.       cout.tie(nullptr);  
  135.    
  136.       #ifndef ONLINE_JUDGE  
  137.             freopen("in.txt""r", stdin);  
  138.       #endif // ONLINE_JUDGE  
  139.    
  140.       Rho::sieve();  
  141.    
  142.       int tc;  
  143.       cin >> tc;  
  144.       while (tc--)  
  145.       {  
  146.             long long a, b;  
  147.             cin >> a >> b;  
  148.             vector <long long> factors_a = Rho::factorize(a);  
  149.             vector <long long> factors_b = Rho::factorize(b);  
  150.             set <long long> st;  
  151.             bool ok = true;  
  152.             for (long long p : factors_a)  
  153.             {  
  154.                   if (st.find(p) != st.end())  
  155.                   {  
  156.                         ok = false;  
  157.                         break;  
  158.                   }  
  159.                   st.insert(p);  
  160.             }  
  161.             for (long long p : factors_b)  
  162.             {  
  163.                   if (st.find(p) != st.end())  
  164.                   {  
  165.                         ok = false;  
  166.                         break;  
  167.                   }  
  168.                   st.insert(p);  
  169.             }  
  170.             cout << (ok ? "YES" : "NO") << '\n';  
  171.       }  
  172. }  

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.