数论模板整理

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<map>
#include<iostream>
using namespace std;
typedef long long ll;
#define pi  acos(-1.0)
const int mod=1e9+7;


const int maxn=1000007;
bool is_prime[maxn];
int prime[maxn];
void AIsieve(int n){
    int cnt=0;
    memset(is_prime,1,sizeof(is_prime));
    is_prime[0]=is_prime[1]=0;
    for(int i=2;i<n;i++){
        if(is_prime[i]){
            prime[cnt++]=i;//保存素数
            for(int j=i*i;j<n;j+=i)//i*i开始进行了稍微的优化
                prime[j]=0;//不是素数
        }
    }
    return ;
}


const int MAXN=3000001;
int prime[MAXN];//保存素数
bool vis[MAXN];//初始化
int LSsieve(int n){
    int cnt=0;
    memset(vis,0,sizeof vis);
    for(int i=2;i<n;i++){
        if(!vis[i]) prime[cnt++]=i;
        for(int j=0;j<cnt&&i*prime[j]<n;j++){
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)   break;
        }
    }
    return cnt;//返回小于n的素数的个数 
}


int phi[maxn];
void phisieve(int n){
    for(int i=1;i<n;i++)  phi[i]=i;
    for(int i=2;i<n;i++)
        if(i==phi[i]) //此时i为素数
            for(int j=i;j<n;j+=i)  //j累加i
                phi[j]=phi[j]/i*(i-1); //j有因子i,而且i是素数,正是欧拉函数
}



//将求素数和欧拉函数值都线性解出
int prime[MAXN];//保存素数
bool vis[MAXN];//初始化
int phi[MAXN];//欧拉函数
void Lphisieve(int n){
    int cnt=0;
    for(int i=2;i<n;i++){
        if(!vis[i]){
            prime[cnt++]=i;
            phi[i]=i-1;// if p is prime,then phi[i]=i-1
        }
        for(int j=0;j<cnt&&i*prime[j]<n;j++){
            int k=i*prime[j];
            vis[k]=true;
            if(i%prime[j]==0){
                phi[k]=phi[i]*prime[j];
                break;
            }
            else   phi[k]=phi[i]*(prime[j]-1);
        }
    }
}

//莫比乌斯函数一般筛法
int mu[1000020];
void sievemu(int n){
    mu[1]=1;
    for(int i=1;i<=n;i++){
        for(int j=i+i;j<=n;j+=i){
            mu[j]-=mu[i];
        }
    }
}


//莫比乌斯函数线性筛法
const int maxn=60000+5;
bool vis[maxn];
int prime[maxn],mu[maxn];
void init_mu(int n){
    int cnt=0;
    mu[1]=1;
    for(int i=2;i<n;i++){
        if(!vis[i]){
            prime[cnt++]=i;
            mu[i]=-1;
        }
        for(int j=0;j<cnt&&i*prime[j]<n;j++){
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)   {mu[i*prime[j]]=0;break;}
            else { mu[i*prime[j]]=-mu[i];}
        }
    }
}

ll mod_pow(ll x,ll n,ll p){
    ll res=1;
    while(n>0){
        if(n&1)    res=res*x%p;
        x=x*x%p;
        n>>=1;
    }
    return res;
}

map<ll,int>mp;
ll bsgs(ll a,ll b,ll c){
    mp.clear();//清空map
    ll tmp,m=ceil(sqrt(c));
    //等于0的情况
    tmp=b%c;
    mp[tmp]=0;
    for(int j=1;j<=m;j++){
        tmp=tmp*a%c;
        mp[tmp]=j;
    }
    tmp=1;
    ll t=mod_pow(a,m,c);
    for(int i=1;i<=m;i++){
        tmp=tmp*t%c;
        if(mp[tmp]) return i*m-mp[tmp];
    }
    return -1;
}
//sqrt(n)求欧拉函数值
ll euler_phi(int n){
    int res=n;
    for(int i=2;i*i<=n;i++){
        if(n%i==0){
            res=res/i*(i-1);
            while(n%i==0) n/=i;
        }
    }
    if(n!=1) res=res/n*(n-1);
    return res;
}

ll inv(int x,int mod){
    return mod_pow(x,mod-2,mod);
}

ll extgcd(ll a,ll b,ll &x,ll &y){
    ll d=a;
    if(b)   d=extgcd(b,a%b,y,x),y-=a/b*x;
    else  x=1,y=0;
    //return (x+b)%b;
    return d;
};
原文地址:https://www.cnblogs.com/elpsycongroo/p/7288380.html