应该是两个算法的入门题、、、认真看了一上午算法导论,做掉了、、
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; }