分解质因数

Pollard-Rho 算法

模板题:P4718 【模板】Pollard-Rho

模板:

const int prl[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};
long long mul(long long a, long long b, long long M){return __int128(a) * b % M;}
long long gcd(long long a, long long b){return __gcd(a, b);}
long long add(long long a, long long b, long long M){a += b; while (a >= M)a -= M; return a;}
long long fpw(long long a, long long b, long long M){long long ret = 1;for (; b; b >>= 1, a = mul(a, a, M))if (b & 1)ret = mul(ret, a, M);return ret;}
bool check(int a, long long v){
	long long d = v - 1, G = fpw(a, d, v);if (G != 1)return 1;
	while ((d & 1) == 0){d >>= 1;if ((G = fpw(a, d, v)) == v - 1)return 0;else if (G != 1)return 1;}
	return 0;
}
bool prm(long long v){
	if (v <= 40){for (int a : prl)if (v == a)return 1;return 0;}
	if (v < (1ll << 32)){if (check(2, v) || check(7, v) || check(61, v))return 0;return 1;}
	for (int a : prl)if (check(a, v))return 0;return 1;
}

long long f(long long x, long long c, long long M){return add(mul(x, x, M), c, M);}
mt19937_64 rnd(time(nullptr));
long long PR(long long v){
	long long c = rnd() % (v - 1) + 1;
	long long t = f(0, c, v), r = f(f(0, c, v), c, v);
	while (t != r){
		long long d = gcd(abs(t - r), v);if (d > 1)return d;
		t = f(t, c, v), r = f(f(r, c, v), c, v);
	}
	return v;
}
long long mxv;
void dfs(long long v){
	if (v < mxv)return;
	if (v < 100){
		for (long long i = 2; i * i <= v; ++i)
			if (v % i == 0){mxv = max(mxv, i);while (v % i == 0)v /= i;}
		if (v != 1)mxv = max(mxv, v);
		return;
	}
	long long d;while ((d = PR(v)) == v);if (prm(d))mxv = max(mxv, d); else dfs(d);
	d = v / d;if (prm(d))mxv = max(mxv, d); else dfs(d);
}
long long get(long long v){mxv = 0; dfs(v); return mxv;}

void work(){
	long long n, v;cin >> n;
	if (prm(n))cout << "Prime" << endl;
	else cout << get(n) << endl;//输出最小质因子
}

期望时间复杂度 \(O(n^{\frac 14})\)

参考

  1. \(\text{12.11 math1.pdf \; \;by Tx\_Lcy}\)
posted @ 2025-04-06 18:41  Hstry  阅读(5)  评论(0)    收藏  举报