Advertisement
Guest User

Untitled

a guest
Feb 19th, 2020
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.67 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. pair<int, int> extendedEuclidean(int a,  int b)
  5. {
  6.     pair<int, int> p, q;
  7.  
  8.     if(a%b==0)
  9.     {
  10.         p.first=0;
  11.         p.second=1;
  12.         return p;
  13.     }
  14.  
  15.     q=extendedEuclidean(b, a%b);
  16.     p.first=q.second;
  17.     p.second=q.first+(-a/b)*q.second;
  18.     return p;
  19.  
  20. }
  21.  
  22. pair<int, int> extendedEuclideanCover(int a, int b)
  23. {
  24.     pair<int, int> p;
  25.     p=extendedEuclidean(abs(a), abs(b));
  26.  
  27.  
  28.     if(a<0)
  29.         p.first=-p.first;
  30.     if(b<0)
  31.         p.second=-p.second;
  32.  
  33.     return p;
  34.  
  35. }
  36.  
  37. int inverse(int a, int m) /// a, m should co prime
  38. {
  39.     pair<int,  int> p=extendedEuclideanCover(a, m);
  40.  
  41.     if(p.first<0)
  42.         p.first+=m;
  43.     return p.first;
  44.  
  45. }
  46. using namespace std;
  47. using cd = complex<double>;
  48. const double PI = acos(-1);/*when invert is true this function will act as inverse dft otherwise dft/ when invert is false/ it take an array of co-efficient  and return as output array / when invert is true / it take an array of output and return array of co-efficient */ void fft(vector<cd> & a, bool invert)
  49. {
  50.     int n = a.size();
  51.     for (int i = 1, j = 0; i < n; i++)
  52.     {
  53.         int bit = n >> 1;
  54.         for (; j & bit; bit >>= 1)
  55.             j ^= bit;
  56.         j ^= bit;
  57.         if (i < j)
  58.             swap(a[i],a[j]);
  59.     }
  60.     for (int len = 2; len <= n; len <<= 1)
  61.     {
  62.         double ang = 2 * PI / len * (invert ? -1 : 1);
  63.         cd wlen(cos(ang), sin(ang));
  64.         for (int i = 0; i < n; i += len)
  65.         {
  66.             cd w(1);
  67.             for (int j = 0; j < len / 2; j++)
  68.             {
  69.                 cd u = a[i+j], v = a[i+j+len/2] * w;
  70.                 a[i+j] = u + v;
  71.                 a[i+j+len/2] = u - v;
  72.                 w *= wlen;
  73.             }
  74.         }
  75.     }
  76.     if (invert)
  77.     {
  78.         for (cd & x : a)
  79.             x /= n;
  80.     }
  81. } /* this function take to array of coefficient of two polynomial
  82. and return an array of coefficient of a polynomial which is multiplication of previous polynomial */
  83. vector<int> multiply(vector<int> const& a, vector<int> const& b)
  84. {
  85.     vector<cd> fa(a.begin(), a.end()), fb(b.begin(), b.end());
  86.     int n = 1;
  87.     while (n < a.size() + b.size())
  88.         n <<= 1;
  89.     fa.resize(n);
  90.     fb.resize(n);
  91.     fft(fa, false);
  92.     fft(fb, false);
  93.     for (int i = 0; i < n; i++)
  94.         fa[i] *= fb[i];
  95.     fft(fa, true);
  96.     vector<int> result(n);
  97.     for (int i = 0; i < n; i++)
  98.         result[i] = round(fa[i].real());
  99.     return result;
  100. }
  101. /** ntt /  calculate those constant first / calculation: / mod=c*2^k+1 / find any c and k; / find g = primitive root of mod / find root=g^c / find root_1=modular multiplicative inverse / root=(1/root)%mod / find root_pw=2^k */ const int mod = 7340033;
  102. const int root = 5;
  103. const int root_1 = 4404020;
  104. const int root_pw = 1 << 20;
  105. void fft(vector<int> & a, bool invert)
  106. {
  107.     int n = a.size();
  108.     for (int i = 1, j = 0; i < n; i++)
  109.     {
  110.         int bit = n >> 1;
  111.         for (; j & bit; bit >>= 1)
  112.             j ^= bit;
  113.         j ^= bit;
  114.         if (i < j)
  115.             swap(a[i], a[j]);
  116.     }
  117.     for (int len = 2; len <= n; len <<= 1)
  118.     {
  119.         int wlen = invert ? root_1 : root;
  120.         for (int i = len; i < root_pw; i <<= 1)
  121.             wlen = (int)(1LL * wlen * wlen % mod);
  122.         for (int i = 0; i < n; i += len)
  123.         {
  124.             int w = 1;
  125.             for (int j = 0; j < len / 2; j++)
  126.             {
  127.                 int u = a[i+j], v = (int)(1LL * a[i+j+len/2] * w % mod);
  128.                 a[i+j] = u + v < mod ? u + v : u + v - mod;
  129.                 a[i+j+len/2] = u - v >= 0 ? u - v : u - v + mod;
  130.                 w = (int)(1LL * w * wlen % mod);
  131.             }
  132.         }
  133.     }
  134.     if (invert)
  135.     {
  136.         int n_1 = inverse(n, mod);
  137.         for (int & x : a)
  138.             x = (int)(1LL * x * n_1 % mod);
  139.     }
  140. } /** primitive root generator */
  141. int powmod (int a, int b, int p) {
  142.     int res = 1;
  143.     while (b)
  144.         if (b & 1)
  145.             res = int (res * 1ll * a % p),  --b;
  146.         else
  147.             a = int (a * 1ll * a % p),  b >>= 1;
  148.     return res;
  149. }
  150. int generator (int p)
  151. {
  152.     vector<int> fact;
  153.     int phi = p-1,  n = phi;
  154.     for (int i=2; i*i<=n; ++i)
  155.         if (n % i == 0)
  156.         {
  157.             fact.push_back (i);
  158.             while (n % i == 0)
  159.                 n /= i;
  160.         }
  161.     if (n > 1)
  162.         fact.push_back (n);
  163.     for (int res=2; res<=p; ++res)
  164.     {
  165.         bool ok = true;
  166.         for (size_t i=0; i<fact.size() && ok; ++i)
  167.             ok &= powmod (res, phi / fact[i], p) != 1;
  168.         if (ok)
  169.             return res;
  170.     }
  171.     return -1;
  172. }
  173.  
  174. int main()
  175. {
  176.     cout<<generator(7340033)<<endl;
  177.     return 0;
  178. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement