应该是两个算法的入门题、、、认真看了一上午算法导论,做掉了、、
RE好多次、、原来是编译器问题 换了C++ 就AC了、、、
乘法要用二进制相乘 否则会爆long long
#include <cstdio>
#include <cstdlib>
#include <ctime>
typedef long long LL;
int T;
LL n, s;
LL factor[110000];
LL mods(LL x, LL y, LL n){
x %= n;
y %= n;
LL tmp = 0;
while(y){
if(y & 1)
tmp = (tmp + x) % n;
x = (x << 1) % n;
y >>= 1;
}
return tmp;
}
LL pow(LL x, LL y, LL n)
{
x %= n;
LL tmp = 1;
while(y){
if(y&1) tmp = mods(tmp, x, n);
x = mods(x, x, n);
y >>= 1;
}
return tmp;
}
int judge(LL tmp, LL n, LL m, LL t){//n - 1 == m * 2^ t
LL tp = m;
LL v = pow(tmp , m, n);
LL last = v;
for(LL i = 1; i <= t; i++){
v = mods(v, v, n);
if(v == 1){
if(last != 1 && last != n-1)
return 0;
}
last = v;
tp <<= 1;
}
if(v == 1)return 1;
return 0;
}
int miller_rubin(LL x, int k){
LL cnt = 0;
LL m = x - 1;
while(!(m & 1)) cnt++, m >>= 1;
while(k--){
LL tmp = rand()%(x-1) + 1;
if(!judge(tmp, x, m, cnt)){
return 0;
}
}
return 1;
}
LL gcd(LL a, LL b){
return b == 0?a: gcd(b, a%b);
}
LL f(LL x, LL n, LL c){
return (mods(x, x, n) + c) % n;
}
LL poll(LL n, LL c){
if(!(n & 1))return 2;
LL x = rand() % n;
LL y = x;
LL i = 1;
LL k = 2;
while(1){
i++;
x = f(x, n, c);
LL d = gcd(y - x + n, n);
if(d != 1 && d != n)
return d;
if(y == x)return n;
if(i == k){
y = x;
k += k;
}
}
}
void find(LL n){
if(miller_rubin(n,5)){
factor[s++] = n;
return;
}
LL p = n;
while(p >= n) p = poll(p, (LL)(rand()%(n-1)+1));
find(p);
find(n/p);
}
int main(){
srand(time(NULL));
scanf("%d",&T);
while(T--){
scanf("%lld",&n);
if(n == 1)break;
s = 0;
find(n);
if(s == 1){
printf("Prime\n");
continue;
}
LL tp = 10000000000LL;
for(int i = 0; i < s; i++){
if(tp > factor[i])
tp = factor[i];
}
printf("%lld\n",tp);
}
return 0;
}