码迷,mamicode.com
首页 > 其他好文 > 详细

数论模板

时间:2019-11-05 00:48:24      阅读:76      评论:0      收藏:0      [点我收藏+]

标签:turn   return   col   mem   com   iso   code   bsp   快速幂   

#### 1.GCD

```C++
ll GCD(ll a,ll b) { return b?GCD(b,a%b):a ;}
```

#### 2.快速GCD(Extend great common divisor)

```C++
ll QGCD(ll l,ll r,ll &x,ll &y)
{
    if(!r)
    {
        x=1;y=0;
        return l;
    }
    else
    {
        ll ans = QGCD(r,l%r,y,x);
        y -= l/r*x;
        return ans;
    }
}
ll kgcd(ll a, ll b)
{
    if (a == 0)
        return b;
    if (b == 0)
        return a;
    if (!(a & 1) && !(b & 1))
        return kgcd(a>>1, b>>1)<<1;
    else if (!(b & 1))
        return kgcd(a, b>>1);
    else if (!(a & 1))
        return kgcd(a>>1, b);
    else
        return kgcd(abs(a - b), min(a, b));
}
```

#### 3.求a关于m的乘法逆元

```c++
ll QGCD(ll l,ll r,ll &x,ll &y)
{
    if(!r)
    {
        x=1;y=0;
        return l;
    }
    else
    {
        ll ans = QGCD(r,l%r,y,x);
        y -= l/r*x;
        return ans;
    }
}
ll mod_inverse(ll a,ll m)
{
    if(QGCD(a,m,x,y)==1) //ax + my = 1
        return (x%m+m)%m;
    return -1;
}

//求逆元:ans = a/b mod m = (a mod (m*b) )/b
```

#### 4.快速幂

```C++
ll qpow(ll a,ll b,ll m)
{
    ll ans = 1 ;
    while(b)
    {
        if(b&1)
            ans = ans*a%m;
        a*=a;
        b>>=1;
    }
    return ans;
}
```

#### 5.快速乘(二分乘法)

```C++
ll qmul(ll a,ll b,ll m)
{
    ll ans = 0 , ch = 1;
    if(a<0) ch = -1,a = -a;
    if(b<0) ch *= -1,b = -b;
    while(b)
    {
        if(b&1)
            ans = (ans+a)%m;
        a=(a*2)%m;
        b>>=1;
    }
    return ans*ch;
}
```

#### 6.中国剩余定理(col = a[i] % m[i] )

```C++
ll QGCD(ll l,ll r,ll &x,ll &y)
{
    if(!r)
    {
        x=1;y=0;
        return l;
    }
    else
    {
        ll ans = QGCD(r,l%r,y,x);
        y -= l/r*x;
        return ans;
    }
}
ll china(ll n,ll *a,ll *m)
{
    ll ans = 1 , col = 0 , y , x ;
    for(int i=1;i<=n;i++)
        ans *= m[i];
    for(int i=1;i<=n;i++)
    {
        cnt = ans/m[i];
        QGCD(m[i],cnt,x,y) ; //m[i]*x+cnt*y = 1;
        col = (col + y*cnt*a[i])%ans;
    }
    return (col+ans)%ans;
}
```

#### 7.筛选素数

```C++
int prime[mxn],vis[mxn];
void Isprime()
{
    mem(vis,1);
    int index = 0 ;
    for(int i=2;i<n;i++)
    {
        if(vis[i])
        {
            prime[index++] = i;
            for(int j=i+i;j<n;j+=i)
                vis[j] = false;
        }
    }
}
```

#### 8.快速计算逆元

```c++
void inverse()
{
    inv[1] = 1;
    for(int i=2;i<n;i++)
    {
        if(i>=m) break;
        inv[i] = (m-m/i)*inv[m%i]%m;
    }
}
```

#### 9.组合数取模

```C++
//1<= n , m <=1e5,预处理逆元和阶乘
ll fac[n] = {1,1},inv[n] = {1,1} , f[n] = {1,1};
ll check(ll a ,ll b)
{
    return b>a? 0 : fac[a]*inv[b]%m*inv[a-b]%m;
}
void init()
{
    for(int i=2;i<n;i++)
    {
        fac[i] = fac[i-1]*i%m;
        f[i] = (m-m/i)*f[m%i]%m;
        inv[i] = inv[i-1]*f[i]%m;
    }
}
//1<=m<=1e5 , n<1e9
ll check(ll n,ll m )
{
    if(m>n) return 0;
    ll ans =1;
    for(int i=1;i<=m;i++)
        ans = ans*(n-i+1)%m*qpow(i,m-2,m)%m;
    return ans;
}


```

#### 10,lucas大组合取模

```C++
//m,m<=1e18 , p<1e5 
#define N 100005
#define M 100007
ll n,m,fac[N]={1};
ll C(ll n,ll m){
    if(m>n)return 0;
    return fac[n]*qpow(fac[m],M-2,M)%M*qpow(fac[n-m],M-2,M)%M;//费马小定理求逆元
}
ll lucas(ll n,ll m){
    if(!m)return 1;
    return(C(n%M,m%M)*lucas(n/M,m/M))%M;
}
void init(){
    for(int i=1;i<=M;i++)
        fac[i]=fac[i-1]*i%M;
}

```

 

数论模板

标签:turn   return   col   mem   com   iso   code   bsp   快速幂   

原文地址:https://www.cnblogs.com/Shallow-dream/p/11795812.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!