题意:求
600851475143
的最大质因子。
分析:依旧考虑两种做法。
1. 直接暴力枚举质因子,
O(n0.5)
。
2. pollard-rho,
O(n0.25logn)。
#include <bits/stdc++.h>
#define ll long long
#define pii std::pair<int,int>
#define mp std::make_pair
#define fi first
#define se second
#define SZ(x) (int)(x).size()
#define pb push_back
template<class T>inline void chkmax(T &x, const T &y) {if(x < y) x = y;}
template<class T>inline void chkmin(T &x, const T &y) {if(x > y) x = y;}
template<class T>
inline void read(T &x) {
char c;int f = 1;x = 0;
while(((c=getchar()) < '0' || c > '9') && c != '-');
if(c == '-') f = -1;else x = c-'0';
while((c=getchar()) >= '0' && c <= '9') x = x*10+c-'0';
x *= f;
}
static int outn;
static char out[(int)2e7];
template<class T>
inline void write(T x) {
if(x < 0) out[outn++] = '-', x = -x;
if(x) {
static int tmpn;
static char tmp[20];
tmpn = 0;
while(x) tmp[tmpn++] = x%10+'0', x /= 10;
while(tmpn) out[outn++] = tmp[--tmpn];
}
else out[outn++] = '0';
}
namespace prime {
const int pn = 11, prime[11] = {2,3,5,7,11,13,17,19,23,29,31};
ll pfac[50], pfacn;
inline ll fmm(ll a, ll b, ll mod) {
ll ret = 0;
while(b) {
if(b&1) (ret += a) %= mod;
(a += a) %= mod, b >>= 1;
}
return ret;
}
inline ll fpm(ll a, ll b, ll mod) {
ll ret = 1;
while(b) {
if(b&1) ret = fmm(ret, a, mod);
a = fmm(a, a, mod), b >>= 1;
}
return ret;
}
inline bool check(int p, int s, ll t, ll n) {
ll k = fpm(p, t, n);
if(k == 1 || k == n-1) return true;
for(int i = 1; i < s; ++i) {
k = fmm(k, k, n);
if(k == n-1) return true;
if(k == 1) return false;
}
return false;
}
inline bool miller_rabin(ll n) {
if(n == 1) return false;
if(n == 2) return true;
if(!(n&1)) return false;
int s = 0;ll t = n-1;
while(!(t&1)) t >>= 1, s++;
for(int i = 0; i < pn && prime[i] < n; ++i)
if(!check(prime[i], s, t, n))
return false;
return true;
}
ll gcd(ll a, ll b) {
return b ? gcd(b, a%b) : a;
}
inline ll pollard_rho(ll n, ll c) {
int i = 1, k = 2;
ll x = rand()%(n-1)+1, y = x;
while(true) {
++i;
x = (fmm(x, x, n)+c)%n;
ll d = gcd(x-y+n, n);
if(d != 1 && d != n) return d;
if(d == n) return n;
if(i == k) {
k <<= 1;
y = x;
}
}
}
void find(ll n) {
if(miller_rabin(n)) {
pfac[++pfacn] = n;
return ;
}
ll p = n;
while(p == n)
p = pollard_rho(p, rand()%n);
find(p), find(n/p);
}
inline ll get_max_prime_factor(ll n) {
pfacn = 0, find(n);
return *std::max_element(pfac+1, pfac+pfacn+1);
}
}
int main() {
std::cout << prime::get_max_prime_factor(600851475143) << std::endl;
return 0;
}