day 5 【B班】wqy数论进阶

费马小定理、欧拉定理与扩展欧拉定理 证明

Miller_Rabin素数测试

int prime[10]={2,3,5,7,11,13,17,19,23,29};


inline int ksc(int a,int k,int mod){
	int res=0;
	for(;k;k>>=1){
		if(k&1)
			res=(res+a)%mod;
		a=(a+a)%mod;
	} 
	return res;
}

inline int ksm(int a,int k,int mod){
	int res=1;
	for(;k;k>>=1){
		if(k&1)
			res=ksc(res,a,mod);
		a=ksc(a,a,mod);
	}
	return res;
}

inline bool Miller_Rabin(int n){
	int q=0,p1=n-1;//将n=2^q+p1; 
	if(n==2)return 1;//特判0,1,2,偶数(因为接下来的只适用于素数) 
	if(n<2 || !(n&1))return 0;
	while(!(p1&1)){//p1不为2就一直分解 
		q++;
		p1>>=1;
	}
	int now;
	for(int i=0;i<10 && prime[i]<n;++i){//测试质数 
		int a=prime[i];
		int last=ksm(a,p1,n);//从a^p1开始测 
		rep(j,1,q){//枚举 
			int now=ksm(last,2,n);
			if(now==1 && last!=1 && last!=n-1)//二次探测定理测试 
				return false;
			last=now;
		}
		if(last!=1)return false;//费马小定理测试 
	} 
	return true;//大概率上是一个质数  
}

#undef int
int main(){
#define int long long
	#ifdef WIN64 
	freopen("mr.txt","r",stdin);
	#endif 
	int range,n;
	rd(range),rd(n); 
    rep(i,1,n){
    	int x;rd(x);
		if(Miller_Rabin(x))  
			printf("Yes
");
    	else  
			printf("No
");
    	
	}
	return 0;
}
原文地址:https://www.cnblogs.com/sjsjsj-minus-Si/p/11634734.html