题目描述:对一个n(2<=n<=2^54),若n是一个素数,输出Prime;否则输出最小的质因数。
我可是一个初中生,会做吗?
如此难的什么费马小定理,还有生日谬论这些坏东西,无语ing。
竟然我用了1周,慢慢看懂了,对自己好满意呀!!!
wea!!!
这些如此难的定理,我怎么可以解释出来呢?希望你们可以看懂我的代码,额,我只能帮各位到这里了。。。wea!!!
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<cstring>
#include<set>
#include<map>
#include<ctime>
#include<vector>
using namespace std;
#define REP(i, a, b) for(int i = (a), _end_ = (b);i <= _end_; ++i)
const int S = 20;
long long ksm(long long a, long long b, long long c) {
a %= c;
b %= c;
long long ret = 0;
while(b) {
if(b & 1) {
ret += a;
ret %= c;
}
a <<= 1;
if(a >= c)
a %= c;
b >>= 1;
}
return ret;
}
long long kzksm(long long x, long long n, long long mod) {
if(n == 1)
return x % mod;
x %= mod;
long long tmp = x;
long long ret = 1;
while(n) {
if(n & 1)
ret = ksm(ret, tmp, mod);
tmp = ksm(tmp, tmp, mod);
n >>= 1;
}
return ret;
}
bool check(long long a, long long n, long long x, long long t) {
long long ret = kzksm(a, x, n);
long long last = ret;
REP(i, 1, t) {
ret = ksm(ret, ret, n);
if(ret == 1 && last != 1 && last != n - 1)
return true;
last = ret;
}
if(ret != 1)
return true;
return false;
}
bool Miller_Rabin(long long n) {
if(n < 2)
return false;
if(n == 2)
return true;
if((n & 1) == 0)
return false;
long long x = n - 1;
long long t = 0;
while((x & 1) == 0) {
x >>= 1;
++t;
}
REP(i, 0, S - 1) {
long long a = rand() % (n - 1) + 1;
if(check(a, n, x, t))
return false;
}
return true;
}
long long factor[100];
int tol;
long long gcd(long long a, long long b) {
if(a == 0)
return 1;
if(a < 0)
return gcd(-a, b);
while(b) {
long long t = a % b;
a = b;
b = t;
}
return a;
}
long long Pollard_rho(long long x, long long c) {
long long i = 1, k = 2;
long long x0 = rand() % x;
long long y = x0;
while(1) {
++i;
x0 = (ksm(x0, x0, x) + c) % x;
long long d = gcd(y - x0, x);
if(d != 1 && d != x)
return d;
if(y == x0)
return x;
if(i == k) {
y = x0;
k += k;
}
}
}
void findfac(long long n) {
if(Miller_Rabin(n)) {
factor[tol++] = n;
return;
}
long long p = n;
while(p >= n)
p = Pollard_rho(p, rand() % (n - 1) + 1);
findfac(p);
findfac(n / p);
}
int main() {
int T;
long long n;
scanf("%d", &T);
while(T--) {
scanf("%I64d", &n);
if(Miller_Rabin(n)) {
printf("Prime\n");
continue;
}
tol = 0;
findfac(n);
long long ans = factor[0];
REP(i, 1, tol - 1)
if(factor[i] < ans)
ans = factor[i];
printf("%I64d\n", ans);
}
return 0;
}