NOI数论姿势瞎总结(Pi也没有)

Miller-Rabin素数检测

费马小定理:没人不会吧。

二次探测:如果\(n\)是质数,\(x^2 \equiv 1\ (\mod n)\)的解只有\(x \equiv 1\)\(x \equiv n-1\ (\mod n)\)

实现方法:

选取一些质数。\(n\)不超过\(3 \times 10^{18}\)的时候只需要\(2 \sim 23\)\(n\)unsigned long long范围内时只需要\(2 \sim 37\)。对于每个质数:

  1. 使用费马小定理的逆否定理检测。

  2. 此时,我们有\(p^{n-1} \equiv 1\ (\mod n)\),如果不出意外\(n\)是质数的话,根据二次探测定理,\(p^{\frac{n-1}{2}},p^{\frac{n-1}{4}}...\)在模意义下都应该为\(1\),直到一次取到\(n-1\)时规律消失。

所以我们可以倒序处理,根据第一次出现\(n-1\)的位置进行探测。

代码

int mi[9]={2,3,5,7,11,13,17,19,23};

inline LL qmul(LL x,LL y,LL mod){
	LL z=(long double)x/mod*y+0.5;
	return ((x*y-z*mod)%mod+mod)%mod;
}

inline LL qpow(LL x,LL y,LL mod){
	LL ret=1,tt=x%mod;
	while(y){
		if(y&1)ret=qmul(ret,tt,mod);
		tt=qmul(tt,tt,mod);
		y>>=1;
	}
	return ret;
}

inline bool miller_rabin(LL x){
	if(x==1)return false;
	rin(i,0,8)if(x==mi[i])return true;
	rin(i,0,8)if(x%mi[i]==0)return false;
	LL a=x-1;int b=0;
	while(!(a&1))a>>=1,++b;
	rin(i,0,8){
		if(qpow(mi[i],x-1,x)!=1)return false;
		LL now=qpow(mi[i],a,x);
		if(now==1||now==x-1)continue;
		rin(j,1,b-1){
			now=qmul(now,now,x);
			if(now==x-1)break;
			if(j==b-1)return false;
		}
	}
	return true;
}

低于线性复杂度的积性函数的前缀和处理方法

看这篇:杜教筛&min_25筛复习

posted on 2019-07-04 21:19  ErkkiErkko  阅读(97)  评论(0编辑  收藏

统计