// ret = (a^b)%n bint mod_exp(bint a,bint p,bint m) { bint exp=a%m, res=1; while(p>1) { if(p&1) res=muti_mod(res,exp,m); exp = muti_mod(exp,exp,m); p>>=1; } return muti_mod(res,exp,m); }
LL pow_mod(LL x, LL n, LL mod) //返回x^n mod c ,非递归版 { if (n == 1) return x % mod; int bit[90], k = 0; while (n) { bit[k++] = n & 1; n >>= 1; } LL ret = 1; for (k = k - 1; k >= 0; k--) { ret = muti_mod(ret, ret, mod); if (bit[k] == 1) ret = muti_mod(ret, x, mod); } return ret; }
bool witness(LL a, LL n, LL x, LL t) //以a为基,n-1=x*2^t,检验n是不是合数 { LL ret = pow_mod(a, x, n); LL last = ret; for (int i = 1; i <= t; i++) { ret = muti_mod(ret, ret, n); if (ret == 1 && last != 1 && last != n - 1) return 1; last = ret; } if (ret != 1) return 1; return 0; }
bint pollard_rho(bint n,int c) { bint x,y,d,i = 1,k = 2; srand(time(0)); x = rand()%(n-1)+1; y = x; while(true) { i++; x = (muti_mod(x,x,n) + c) % n; d = gcd(y-x, n); if (1 < d && d < n) return d; if( y == x) return n; if(i == k) { y = x; k <<= 1; } } }
//miller-rabin bool miller_rabin(bint n, int times) { if(n==2)return 1; if(n<2||!(n&1))return 0; bint a, u=n-1, x, y; int t=0; while(u%2==0) { t++; u/=2; } srand(time(0)); for(int i=0; i<times; i++) { a = rand() % (n-1) + 1; x = mod_exp(a, u, n); for(int j=0; j<t; j++) { y = muti_mod(x, x, n); if ( y == 1 && x != 1 && x != n-1 ) return false; //must not x = y; } if( y!=1) return false; } return true; }
LL Pollard_rho(LL x, LL c) { LL i = 1, x0 = rand() % x, y = x0, k = 2,d; while (1) { i++; x0 = (muti_mod(x0, x0, x) + c) % x; if (y == x0) return x; if(y>x0) d = gcd(y - x0, x); else d = gcd(x0 - y, x); if (d != 1 && d != x) return d; if (i == k) { y = x0; k += k; } } }