大数分解
const int S=8;//随机算法判定次数一般8~10就够了 //计算 ret=(a*b)%c a,b,c<2^63 ll mult_mod(ll a,ll b,ll c) { a%=c; b%=c; ll ret=0; ll tmp=a; while(b) { if(b&1) { ret+=tmp; if(ret>c) ret-=c;//直接取模慢很多 } tmp<<=1; if(tmp>c) tmp-=c; b>>=1; } return ret; } //计算ret=(a^n)%mod ll pow_mod(ll a,ll n,ll mod) { ll ret=1; ll temp=a%mod; while(n) { if(n&1) ret=mult_mod(ret,temp,mod); temp=mult_mod(temp,temp,mod); n>>=1; } return ret; } //通过a^n(n-1)=1(mod n)来判断 n 是不是素数 //n-1=x * 2^t 中间使用二次判断 //是合数返回true ,不一定是合数返回false bool check(ll a,ll n,ll x,ll t) { ll ret=pow_mod(a,x,n); ll last=ret; for(int i=1;i<=t;i++) { ret=mult_mod(ret,ret,n); if(ret==1&&last!=1&&last!=n-1) return true; last=ret; } if(ret!=1) return true; else return false; } // Miller_Rabin算法进行素数测试 //速度快可以判断一个 < 2^63 的数是不是素数 //是素数返回true,(可能是伪素数) //不是素数返回false bool Miller_Rabin(ll n) { if(n<2) return false; if(n==2) return true; if((n&1)==0) return false;//偶数 ll x=n-1; ll t=0; while((x&1)==0) { x>>=1; t++; } srand(time(NULL)); for(int i=0;i<S;i++) { ll a=rand()%(n-1)+1; if(check(a,n,x,t)) return false; } return true; } // pollard_rho算法进行质因素分解 vector<ll>factor;//质因数分解结果 (刚返回时是无序的) //int tol;//质因数的个数 编号0~tol-1; ll gcd(ll a,ll b) { ll t; while(b) { t=a; a=b; b=t%b; } if(a>=0) return a; else return -a; } //找出一个因子 ll pollard_rho(ll x,ll c) { ll j=1,k=2; srand(time(NULL)); ll x0=rand()%(x-1)+1; ll y=x0; while(1) { j++; x0=(mult_mod(x0,x0,x)+c)%x; ll d=gcd(y-x0,x); if(d!=1&&d!=x) return d; if(y==x0) return x; if(j==k) { y=x0; k+=k; } } } //对n进行素因子分解,存入vector,k设置为107左右即可 void findfac(ll n,int k) { if(n==1) return ; if(Miller_Rabin(n)) { factor.push_back(n); return ; } ll p=n; int c=k; while(p>=n) p=pollard_rho(p,c--); findfac(p,k); findfac(n/p,k); } void solve(){ factor.clear(); ll n; cin>>n; findfac(n,107); ll te=1; for(auto i:factor){ te*=i; } if(te==n){ cout<<"no"<<endl; } else{ cout<<"yes"<<endl; } }
rush!