a53

PrimeXXL

a53
Sep 15th, 2020
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.88 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. ifstream fin("primexxl.in");
  5. ofstream fout("primexxl.out");
  6.  
  7. #define forn(i,n) for (int i=0;i<(int)(n);i++)
  8.  
  9. #define dforn(i,n) for(int i=(int)((n)-1);i>=0;i--)
  10.  
  11. typedef long long tint;
  12.  
  13. typedef tint tipo;
  14.  
  15. #define BASEXP 6
  16.  
  17. #define BASE 1000000
  18.  
  19. #define LMAX 200 // Needs to be varied acording to the size of the numbers to be tested. LMAX = 200 works fine for 300 digit primes
  20.  
  21.  
  22.  
  23. struct Long {
  24.  
  25. int l;
  26.  
  27. tipo n[LMAX];
  28.  
  29. Long(tipo x) { l = 0; forn(i, LMAX) { n[i]=x%BASE; l+=!!x||!i; x/=BASE;} }
  30.  
  31. Long(){*this = Long(0);}
  32.  
  33. Long(string x) {
  34.  
  35. l=(x.size()-1)/BASEXP+1;
  36.  
  37. fill(n, n+LMAX, 0);
  38.  
  39. tipo r=1;
  40.  
  41. forn(i, x.size()){
  42.  
  43. n[i / BASEXP] += r * (x[x.size()-1-i]-'0');
  44.  
  45. r*=10; if(r==BASE)r=1;
  46.  
  47. }
  48.  
  49. }
  50.  
  51. };
  52.  
  53. void out(Long& a) {
  54.  
  55.  
  56.  
  57. char msg[BASEXP+1];
  58.  
  59. cout << a.n[a.l-1];
  60.  
  61. dforn(i, a.l-1) {
  62.  
  63. sprintf(msg, "%6.6llu", a.n[i]); cout << msg; // 6 = BASEXP!
  64.  
  65. }
  66.  
  67. cout << endl;
  68.  
  69. }
  70.  
  71. void invar(Long &a) {
  72.  
  73. fill(a.n+a.l, a.n+LMAX, 0);
  74.  
  75. while(a.l>1 && !a.n[a.l-1]) a.l--;
  76.  
  77. }
  78.  
  79. void lsuma(const Long&a, const Long&b, Long &c) { // c = a + b
  80.  
  81. c.l = max(a.l, b.l);
  82.  
  83. tipo q = 0;
  84.  
  85. forn(i, c.l) q += a.n[i]+b.n[i], c.n[i]=q%BASE, q/=BASE;
  86.  
  87. if(q) c.n[c.l++] = q;
  88.  
  89. invar(c);
  90.  
  91. }
  92.  
  93. Long& operator+= (Long&a, const Long&b) { lsuma(a, b, a); return a; }
  94.  
  95. Long operator + (const Long&a, const Long&b) { Long c; lsuma(a, b, c); return c;}
  96.  
  97. bool lresta(const Long&a, const Long&b, Long&c) { // c = a - b
  98.  
  99. c.l = max(a.l, b.l);
  100.  
  101. tipo q = 0;
  102.  
  103. forn(i, c.l) q += a.n[i] - b.n[i], c.n[i]=(q+BASE)%BASE, q=(q+BASE)/BASE-1;
  104.  
  105. invar(c);
  106.  
  107. return !q;
  108.  
  109. }
  110.  
  111. Long& operator-= (Long&a, const Long&b) { lresta(a, b, a); return a;}
  112.  
  113. Long operator- (const Long&a, const Long&b) {Long c; lresta(a, b, c); return c;}
  114.  
  115. bool operator< (const Long&a, const Long&b) { Long c; return !lresta(a, b, c); }
  116.  
  117. bool operator<= (const Long&a, const Long&b) { Long c; return lresta(b, a, c); }
  118.  
  119. bool operator== (const Long&a, const Long&b) { return a <= b && b <= a; }
  120.  
  121. void lmul(const Long&a, const Long&b, Long&c) { // c = a * b
  122.  
  123. c.l = a.l+b.l;
  124.  
  125. fill(c.n, c.n+c.l, 0);
  126.  
  127. forn(i, a.l) {
  128.  
  129. tipo q = 0;
  130.  
  131. forn(j, b.l) q += a.n[i]*b.n[j]+c.n[i+j], c.n[i+j] = q%BASE, q/=BASE;
  132.  
  133. c.n[i+b.l] = q;
  134.  
  135. }
  136.  
  137. invar(c);
  138.  
  139. }
  140.  
  141. Long& operator*= (Long&a, const Long&b) { Long c; lmul(a, b, c); return a=c; }
  142.  
  143. Long operator* (const Long&a, const Long&b) { Long c; lmul(a, b, c); return c; }
  144.  
  145. void lmul (const Long&a, tipo b, Long&c) { // c = a * b
  146.  
  147. tipo q = 0;
  148.  
  149. forn(i, a.l) q+= a.n[i]*b, c.n[i] = q%BASE, q/=BASE;
  150.  
  151. c.l = a.l;
  152.  
  153. while(q) c.n[c.l++] = q%BASE, q/=BASE;
  154.  
  155. invar(c);
  156.  
  157. }
  158.  
  159. Long& operator*= (Long&a, tipo b) { lmul(a, b, a); return a; }
  160.  
  161. Long operator* (const Long&a, tipo b) { Long c = a; c*=b; return c; }
  162.  
  163. void ldiv(const Long& a, tipo b, Long& c, tipo& rm) { // c = a / b; rm = a % b
  164.  
  165. rm = 0;
  166.  
  167. dforn(i, a.l) {
  168.  
  169. rm = rm * BASE + a.n[i];
  170.  
  171. c.n[i] = rm / b; rm %= b;
  172.  
  173. }
  174.  
  175. c.l = a.l;
  176.  
  177. invar(c);
  178.  
  179. }
  180.  
  181. Long operator/ (const Long&a, tipo b) { Long c; tipo r; ldiv(a, b, c, r); return c;}
  182.  
  183. Long operator% (const Long&a, tipo b) { Long c; tipo r; ldiv(a, b, c, r); return r;}
  184.  
  185. void ldiv(const Long& a, const Long& b, Long& c, Long& rm) { // c = a / b; rm = a % b
  186.  
  187. rm = 0;
  188.  
  189. dforn(i, a.l) {
  190.  
  191. if (rm.l == 1 && rm.n[0] == 0) {
  192.  
  193. rm.n[0] = a.n[i];
  194.  
  195. }
  196.  
  197. else {
  198.  
  199. dforn(j, rm.l) rm.n[j+1] = rm.n[j];
  200.  
  201. rm.n[0] = a.n[i]; rm.l++;
  202.  
  203. }
  204.  
  205. tipo q = rm.n[b.l] * BASE + rm.n[b.l-1];
  206.  
  207. tipo u = q / (b.n[b.l-1] + 1);
  208.  
  209. tipo v = q / b.n[b.l-1] + 1;
  210.  
  211. while (u < v-1) {
  212.  
  213. tipo m = (u+v)/2;
  214.  
  215. if (b*m <= rm) u=m; else v = m;
  216.  
  217. }
  218.  
  219. c.n[i] = u;
  220.  
  221. rm -= b*u;
  222.  
  223. }
  224.  
  225. c.l = a.l;
  226.  
  227. invar(c);
  228.  
  229. }
  230.  
  231. Long operator/ (const Long&a, const Long& b) { Long c,r; ldiv(a, b, c, r); return c;}
  232.  
  233. Long operator% (const Long&a, const Long& b) { Long c,r; ldiv(a, b, c, r); return r;}
  234.  
  235.  
  236.  
  237. typedef Long ll;
  238.  
  239.  
  240.  
  241. ll gcd (ll a, ll b) { // Computes the greatest common divisor using Euclid's algorithm
  242.  
  243. ll t;
  244.  
  245. while (!(b == 0)) {
  246.  
  247. t = b;
  248.  
  249. b = a % b;
  250.  
  251. a = t;
  252.  
  253. }
  254.  
  255. return a;
  256.  
  257. }
  258.  
  259.  
  260.  
  261. ll modexp(ll a, ll b, ll n) { // Performs modular exponentiation by repeated squaring
  262.  
  263. ll c = 1;
  264.  
  265. while (!(b <= 1)) {
  266.  
  267. if (b % 2 == 0) {
  268.  
  269. a *= a;
  270.  
  271. a = a % n;
  272.  
  273. b = b / 2;
  274.  
  275. }
  276.  
  277. else {
  278.  
  279. c = c * a;
  280.  
  281. c = c % n;
  282.  
  283. b = b - 1;
  284.  
  285. }
  286.  
  287. }
  288.  
  289. return (a * c) % n;
  290.  
  291. }
  292.  
  293.  
  294.  
  295. bool isprime (ll n, int rounds) { // Does 'rounds' iterations of Rabin-Miller primality test
  296.  
  297. unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
  298.  
  299. mt19937 g1 (seed);
  300.  
  301. uniform_int_distribution<tipo> distribution(0, BASE-1);
  302.  
  303. vector <ll> bases(rounds);
  304.  
  305. for (int c = 0; c < rounds; c++) {
  306.  
  307. bases[c].l = n.l;
  308.  
  309. forn(i, n.l) {
  310.  
  311. bases[c].n[i] = distribution(g1);
  312.  
  313. }
  314.  
  315. invar(bases[c]);
  316.  
  317. if (n <= bases[c]) c--;
  318.  
  319. }
  320.  
  321. if (n == 2) return true;
  322.  
  323. if (n == 1 || n % 2 == 0) return false;
  324.  
  325. ll d, x, b;
  326.  
  327. tipo k;
  328.  
  329. tipo s = 0;
  330.  
  331. d = n - 1;
  332.  
  333. while (d % 2 == 0) {
  334.  
  335. s = s + 1;
  336.  
  337. d = d / 2;
  338.  
  339. }
  340.  
  341. for (int c = 0; c < rounds; c++) {
  342.  
  343. b = bases[c];
  344.  
  345. if (n <= b) continue;
  346.  
  347. if (!(gcd(b,n) == 1)) {
  348.  
  349. if (b == n) continue;
  350.  
  351. else return false;
  352.  
  353. }
  354.  
  355. x = modexp(b,d,n);
  356.  
  357. if ((x == 1) || (x == n -1)) continue;
  358.  
  359. for(k = 1; k < s; k++) {
  360.  
  361. x = (x*x) % n;
  362.  
  363. if (x == n-1) break;
  364.  
  365. if (x == 1) return false;
  366.  
  367. }
  368.  
  369. if (k == s) return false;
  370.  
  371. if (s == 1 && !(x == n - 1)) return false;
  372.  
  373. }
  374.  
  375. return true;
  376.  
  377. }
  378.  
  379.  
  380.  
  381. int main() { // It reads input from stdin, first the ammount of numbers to be tested and then the numbers
  382.  
  383. int t;
  384.  
  385. string s;
  386.  
  387. fin >> s;
  388.  
  389.  
  390. ll N(s);
  391.  
  392. if (isprime(N, 1)) fout << "DA" << endl; // Modify the '10' parameter to alter the ammount of RM rounds
  393.  
  394. else fout << "NU" << endl;
  395.  
  396. return 0;
  397.  
  398. }
  399.  
Add Comment
Please, Sign In to add comment