【笔记】【模板】Pollard's Rho算法

快速乘

typedef long long ll;
ll mul(ll a, ll b, ll p) {
  ll ans = (ll)((long double)a*b/p+0.5)-c*p;
  return ans<0?ans+p:ans;
}

Miller-Rabin

ll qpow(ll a, ll b, ll n) {
	ll ans = 1;
	for (; b; b >>= 1, a = mul(a,a,n))
		if (b & 1) ans = mul(ans,a,n);
	return ans;
}

bool MR(ll n) {
	if (n == 2) return true;
	if (n < 2 || (~n & 1)) return false;
	ll p = n-1; int cnt = 0;
	while (~p & 1) p >>= 1, ++cnt;
	for (int i = 0; i < 10; ++i) {
		ll x = qpow((ll)rand()*rand()%(n-1)+1, p, n), lst = 0;
		for (int j = 0; j < cnt; ++j) {
			lst = x;
			x = mul(x, x, n);
			if (x == 1 && (lst != n-1 && lst != 1)) return false;
		}
		if (x != 1) return false;
	}
	return true;
}

Pollard-Rho

ll gcd(ll x, ll y) {
	while (y != 0) {
		x %= y;
		swap(x, y);
	}
	return x;
}

ll pr(ll n) {
	ll x = (ll)rand()*rand()%(n-1)+1, c = rand()%(n-1)+1, y = x, i = 1, k = 1, j = 1;
	while (1) {
		x = (mul(x,x,n)+c)%n;
		j = mul(j,abs(y-x),n);
		if ((k-i)%127 == 0) {
			ll d = gcd(n, j);
			if (d > 1) return d;
		}
		if (i++ == k) {
			y = x;
			k <<= 1;
		}
	}
}
posted @ 2021-05-20 20:27  frank3215  阅读(90)  评论(0编辑  收藏  举报