数论模板

Do more with less

欧几里德算法(辗转相除法)

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

唯一分解定理

int judge(int *x)
{
    x[2] /= gec(x[2],x[1]);
    for(int i = 2; i <= k; i ++)
        x[2] /= gcd(x[i],x[2]);
}

扩展欧几里德

void gcd(int a, int b, int &d, int &x, int &y)
{
    if(!b)
    {
        d = a;
        x = 1;
        y = 0;  
    }   
    else
    {
        gcd(b, a%b, y, x);
        y -= x * (a/b);
    }
}

Eratosthenes筛法

void eratosthenes()
{
    memset(prime,true,sizeof(prime));
    prime[0]=prime[1]=false;
    for(int i=2;i<=sqrt(N);i++)
        if(prime[i])
            for(int j=i*i;j<N;j+=i)
                prime[j]=false;

}

模算术公式

(a+b)modn=((amodn)+(bmodn))modn
(ab)modn=((amodn)(bmodn)+n)modn
abmodn=(amodn)(bmodn)modn

int mul_mod(int a, int b, int n)
{
    a %= n;
    b %= n;
    return (int)((long long )a * b % n);
}

大整数取模

int main()
{
    char n[MAXN];
    int m;
    scanf("%d", n, &m);
    int len = strlen(n);
    int sns = 0;
    for(int i = 0; i < len; i ++)
        ans = (int )(((long long)ans*10 +n[i]- '0')%m);
    printf("%d\n");
    return 0;
}

幂取模(快速幂)


int pow_mod(int a, int n, int m)
{
    int ans = 1;
    for(int i = 0; i < n; i ++)
        ans = (int)((long long)ans * a % m);
}

幂取模(递归写法)

int pow_mod(int a, int n, int  m)
{
    if(n == 0)
        return 1;
    int x = pow_mod(a, n/2, m);
    long long ans = (long long )x * x % m;
    if(n%2 == 1)
        ans = ans *a % m;
    return (int )ans;
}

快速幂(非递归)

LL pow_mod(LL a, LL b, LL p){//a的b次方求余p 
    LL ret = 1;
    while(b){
        if(b & 1) ret = (ret * a) % p;
        a = (a * a) % p;
        b >>= 1;
    }
    return ret;
}

快乘

LL mul(LL a, LL b, LL p){//快速乘,计算a*b%p 
    LL ret = 0;
    while(b){
        if(b & 1) ret = (ret + a) % p;
        a = (a << 1) % p;
        b >>= 1;
    }
    return ret;
}

欧拉函数

int euler(int x) 
{
     int i, res = x;
     for (i = 2;i < (int)sqrt(x * 1.0) + 1; i++)
         if(x % i == 0) 
         {
            res = res / i * (i - 1);
            while(x % i == 0) 
                x /= i; // 保证 i 一定是素数
         }
     if(x > 1)
        res = res / x * (x - 1);
     return res;
} 

中国剩余定理

//n个方程:x=a[i](mod m[i]) (0<=i<n)
LL china(int n, LL *a, LL *m){
    LL M = 1, ret = 0;
    for(int i = 0; i < n; i ++) M *= m[i];
    for(int i = 0; i < n; i ++){
        LL w = M / m[i];
        ret = (ret + w * inv(w, m[i]) * a[i]) % M;
    }
    return (ret + M) % M;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值