数论基本算法

这篇blog简单总结一下一些基本的数论算法,包括gcd,ex_gcd,和素数的一些基本算法,

公约数

gcd

LL gcd(LL a,LL b)
{
    return b==0? a:gcd(b,a%b);
}

ex_gcd

//返回值为最大公约数
LL ex_gcd(LL a,LL b,LL &x,LL &y)
{
    LL d = a;
    if(!b){x = 1,y = 0;}
    else{
      d = ex_gcd(b,a%b,y,x);
      y-=a/b*x;
    }
    return d;
}

素数

素数判定

bool isPrime(int n)
{
    for(int i=2 ; i*i<=n ; ++i)
        if(n%i == 0)return false;
    return n!=1;
}

求一个数的约数

void divisor(int n,vector<int>& div)
{
    int i;
    for( i = 1 ; i*iif(n%i==0){
            div.push_back(i);div.push_back(n/i);
        }
    }
    if(i*i==n)div.push_back(i);
}

素因子分解

void prime_factor(int n,map<int,int> &pf)
{
    for(int i =2 ; i*i<=n ; ++i)
    {
        while(n%i==0)
        {
            ++pf[i];
            n/=i;
        }
    }
    if(n!=1)pf[n] = 1;
}

Eratosthenes筛法

void Eratosthenes(int n)
{
    memset(is_prime,true,sizeof(is_prime));

    for(int i = 2 ; i*i<=n; ++i)
        if(is_prime[i])
        for(int j=i*i ; j<=n ; j+=i)is_prime[j] = false;
}

区间筛法

void segment_sieve(LL a,LL b)//[a,b]
{
    memset(is_prime_ab,true,sizeof(is_prime_ab[0])*(b-a+1));
    memset(is_prime_sqrtb,true,sizeof(is_prime_sqrtb[0])*(sqrt(b)+2));
    for(LL i = 2 ; i*i<=b ; ++i)
    if(is_prime_sqrtb[i]){
        for( LL j = i*i ; j*j<=b ; j+=i)is_prime_sqrtb[j] = false;
        for(LL j = max(i*i,(a-1)/i+1)*i ; j<=b ; j+=i)is_prime_ab[j-a] = false;
    }
}

简单模运算

power_mod

LL power_mod(LL x,LL n,LL mod)
{
    LL res = 1;
    while(n)
    {
        if(n&1)res = (res*x)%mod;
        x = (x*x)%mod;
        n>>=1;
    }
    return res;
}

大整数取模

LL big_mod(string val,LL mod)
{
    LL res = 0;
    for(int i=0 ; i<val.length() ; ++i)
    {
        res = ((res)*10+val[i]-'0')%mod;
    }
    return res;
}

你可能感兴趣的:(算法&数据结构)