POJ - 1811 Prime Test
pallord-rho模板
不能srand,不能srand,不能srand
为此RE了40min
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<ctime>
const int N=1e5+7;
typedef long long LL;
using namespace std;
int T;
LL x,p[N];
template<typename T> void read(T &x) {
T f=1; x=0; char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
LL ksc(LL a,LL b,LL mod) {
LL base=a%mod,res=0;
while(b) {
if(b&1) res=(res+base)%mod;
base=(base+base)%mod;
b>>=1;
}
return res;
}
LL ksm(LL a,LL b,LL mod) {
LL base=a,res=1;
while(b) {
if(b&1) res=ksc(res,base,mod);
base=ksc(base,base,mod);
b>>=1;
}
return res;
}
int miller_rabin(LL n) {
LL u=n-1;
int k=0;
if(n==2||n==3||n==5||n==7||n==11) return 1;
if(!(n%2)||!(n%3)||!(n%5)||!(n%7)||!(n%11)) return 0;
while(!(u&1)) {
u>>=1; k++;
}
for(int i=1;i<=20;i++) {
LL x=rand()%(n-2)+2;
LL tp=ksm(x,u,n);
for(int j=1;j<=k;j++) {
LL tpp=ksc(tp,tp,n);
if(tpp==1&&tp!=1&&tp!=n-1) return 0;
tp=tpp;
}
if(tp!=1) return 0;
}
return 1;
}
LL gcd(LL a,LL b) {return (!b)?a:gcd(b,a%b);}
LL pallord_rho(LL n,int c) {
LL x=rand()%n,y=x;
int k=2,i=1;
for(;;) {
i++;
x=(ksc(x,x,n)+c)%n;
LL tp=gcd((x-y+n)%n,n);
if(tp>1&&tp<n) return tp;
if(x==y) return n;
if(i==k) y=x,k+=k;
}
}
void find(LL n) {
if(miller_rabin(n)) {
p[++p[0]]=n;
return ;
}
LL p=n;
for(int c=13;;c++) {
p=pallord_rho(n,c);
if(p>1&&p<n) break;
}
find(p); find(n/p);
}
int main() {
read(T);
while(T--) {
p[0]=0;
read(x);
if(x==1||miller_rabin(x)) puts("Prime");
else {
find(x);
LL ans=p[1];
for(int i=2;i<=p[0];i++) ans=min(ans,p[i]);
printf("%lld\n",ans);
}
}
return 0;
}