题解:JudgeOnline/upload/201604/sol.doc
PS linux下RAND_MAX是2^31!!TLE了快一页 另一题4522跟着一起T
#include<cstdio> #include<cstdlib> #include<ctime> #include<algorithm> #include<cmath> #include<map> using namespace std; typedef long long ll; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read(ll &x) { char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } inline ll Random(ll n) { // return (ll)((double)rand()/(RAND_MAX+1)*n); return (ll)rand()*rand()%n; } inline ll gcd(ll a,ll b) { return b!=0?gcd(b,a%b):a; } inline ll Mul(ll a,ll b,ll p) { a%=p; b%=p; ll t=(a*b-(ll)((double)a/p*b+0.5)*p); return t<0?t+p:t; } inline ll Pow(ll a,ll b,ll p) { ll t=1; for(;b;b>>=1,a=Mul(a,a,p)) if(b&1) t=Mul(t,a,p); return t; } inline bool Witness(ll a,ll p,ll s,ll t) { ll x0,x1; x0=Pow(a,t,p); while (s--) { x1=Mul(x0,x0,p); if (x1==1 && x0!=1 && x0!=p-1) return true; x0=x1; } if (x0!=1) return true; return false; } inline bool Miller(ll p) { if (p<2) return false; if (p==2 || p==3) return true; if (~p&1) return false; if(p%6!=1 && p%6!=5) return false; ll s=0,t=p-1; while (~t&1) s++,t>>=1; ll a; for (int i=1;i<=5;i++) { a=Random(p-1)+1; if (Witness(a,p,s,t)) return false; } return true; } ll rho(ll n,ll c) { ll k=2,x=Random(n),y=x,p=1; for(ll i=1;p==1;i++) { x=(Mul(x,x,n)+c)%n; p=abs(x-y); p=gcd(n,p); if(i==k) y=x,k<<=1; } return p; } ll n; map<ll,int> Map; typedef map<ll,int>::iterator ITER; void Calc(ll n,ll c) { if(n==1) return; if(Miller(n)) { Map[n]++; return; } ll t=n; // while(t==n) t=rho(n,Random(n-1)+1); ll k=c; while(t==n) t=rho(n,k--); Calc(t,c); Calc(n/t,c); } inline int Query(){ read(n); ll Sqr=(ll)sqrt(n); if (Sqr*Sqr==n) return 1; ll itmp=n; while (1) { if (itmp%8==7) return 4; if (itmp%4==0) itmp/=4; else break; } Map.clear(); Calc(n,5); int flag=0; for (ITER it=Map.begin();it!=Map.end() && !flag;it++) { // printf("%lld %d\n",it->first,it->second); if (it->first%4==3 && it->second%2!=0) flag=1; } if (!flag) return 2; return 3; } int main() { srand(10086); ll Q; freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(Q); while (Q--) printf("%d\n",Query()); return 0; }