Pollard-Rho

  • 不会复杂度,正确性
  • 核心思想 \(\rightarrow\) 生日悖论

Miller-Rabin素性测试

分为两步,判断 \(p\) 是否是素数

1, 取一个底数 \(a\)\(2^{31}\) 以内取 \(\{ 2,7,61 \}\) 三个即可

2,设 \(2^tu=p-1\),依次判断 \(a^{2^ku}(0\le k\le t)\) 是否等于 \(1\),如果是,那么通过当前测试

bool P(ll n) {
	if(n < 3 || !(n & 1)) return n == 2;
	if(n % 3 == 0) return n == 3;
	ll u = n - 1, t = 0, tst = 6;
	while(!(u & 1)) u /= 2, ++t;
	while(tst--) {
		ll a = rd() % (n - 3) + 2, v = qp(a, u, n);
		if(v == 1) continue;
		int s;
		for(s = 0; s < t; s++) {
			if(v == n - 1) break;
			v = (i2) v * v % n;
		}
		if(s == t) return 0;
	}
	return 1;
}

Pollard-Rho

每次随机取出两个数,判断 \(gcd(abs(x-y),n)\) 是否大于 \(1\)

随机取基于一个函数 \(f(x)=x^2+c\) 采用龟兔赛跑制,每次 \(x\) 变化一次,\(y\) 变化两次,即 \(x=f(x) \ \ \ \ y = f(f(y))\)

ll f(ll x, ll c, ll n) {return ((i2) x * x + c) % n;}

inline ll A(ll x) {return x > 0 ? x : -x;}

ll pr(ll n) {
	if(n == 4) return 2;//奇妙特判?构造的函数有问题 
	ll c = rd() % (n - 1) + 1;
	ll t = f(0, c, n), r = f(t, c, n);
	while(t != r) {
		ll d = __gcd(A(t - r), n);
		if(d > 1) return d;
		t = f(t, c, n), r = f(f(r, c, n), c, n);
	}
	return n;
}

void fac(ll x) {
	if(x <= mp || x < 2) return;
	if(P(x)) {mp = x; return;}
	ll p = x;
	while(p >= x) p = pr(x);
	while(!(x % p)) x /= p;
	fac(x), fac(p);
}

时间复杂度是 \(O(n^{\frac{1}{4}})\)

posted @ 2024-09-23 21:08  gzyqwq  阅读(0)  评论(0编辑  收藏  举报