数论模板

数论:

快速乘:

ll ModMul(ll a,ll b,ll n){//快速积取模 a*b%n
    ll ans=0;
    while(b){ if(b&1) ans=(ans+a)%n; a=(a+a)%n; b>>=1; } return ans; }

 

快速幂:

ll ModExp(ll a,ll b,ll n){  //快速幂取模 a^b%n
    ll ans=1;
    while(b){ if(b&1) ans=ModMul(ans,a,n); a=ModMul(a,a,n); b>>=1; } return ans; }

 

Miller-Rabin素数检测算法:

bool miller_rabin(ll n){
    ll i,j,a,x,y,t,u,s=10;
    if(n==2) return true; if(n<2||!(n&1)) return false; for(t=0,u=n-1;!(u&1);t++,u>>=1); //n-1=u*2^t for(i=0;i){ a=rand()%(n-1)+1; x=ModExp(a,u,n); for(j=0;j){ y=ModMul(x,x,n); if(y==1&&x!=1&&x!=n-1) return false; x=y; } if(x!=1) return false; } return true; }

素数筛(线性筛):

const ll maxn=100000001;
ll prime[maxn];      //就是个素数表
bool sf[maxn];        //判断这个数是不是素数,sf[i]中的i是从1到maxn的数
void sushu()
{         //核心 欧拉筛代码
    ll num=0;        //num 用来记筛到第几个质数
    memset(sf,true,sizeof(sf));
    sf[1] = false;
    sf[0] = false;  //1 0 特判 
    for(int i = 2;i <= maxn; i ++)
    {          //外层枚举1~maxn
        if(sf[i]) prime[++num] = i;      //如果是质数就加入素数表
        for(int j = 1;j <= num;j ++)
        {       //内层枚举num以内的质数
            if(i * prime[j] > maxn) break; //筛完结束
            sf[i * prime[j]] = false;      //筛掉...
            if(i % prime[j] == 0) break;   //避免重复筛
        }
    } 
}

 

你可能感兴趣的:(数论模板)