快速素數測試(Miller-Robin)
阿新 • • 發佈:2020-12-02
ll fm(ll x,ll y,ll mod){ ll ans=0; while(y>0){ if(y&1)ans=(ans+x)%mod; y>>=1; x=(x+x)%mod; } return ans; } ll fp(ll b,ll p,ll mod){ ll ans=1; while(p){ if(p&1)ans=ans*b%mod; p>>=1; b=b*b%mod; } return ans; } int strong_pseudo_primetest(ll n, int base) { ll n2 = n - 1, res; int s = 0; while (n2 % 2 == 0) n2 >>= 1, s++; res = fp(base, n2, n); if ((res == 1) || (res == n - 1)) return 1; s--; while (s >= 0) { res = fm(res, res, n); if (res == n - 1) return 1; s--; } return 0;// n is not a strong pseudo prime } int isprime(ll n) { static ll testNum[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}; static ll lim[] = {4, 0, 1373653ll, 25326001ll,25000000000ll, 2152302898747ll, 3474749660383ll, 341550071728321ll,0, 0, 0, 0}; if (n < 2 || n == 3215031751ll) return 0; for (int i = 0; i < 12; ++i) { if (n < lim[i]) return 1; if (strong_pseudo_primetest(n, testNum[i]) == 0) return 0; } return 1; }