zoukankan      html  css  js  c++  java
  • [学习笔记]中国剩余定理

    中国剩余定理

    以前公式用的是图片导致排版丑陋,今天复习顺便重写了

    描述

    有同余方程组:

    [left{ egin{matrix} x equiv a_1 (mod m_1) \ x equiv a_2 (mod m_2) \ ... \ x equiv a_k (mod m_k) end{matrix} ight. \ 其中m_i两两互质 ]

    (M = prod_{i = 1}^{k} m_i),则方程组的一个解为(x = sum_{i = 1}^{k} a_i cdot frac{M}{m_i} cdot (frac{M}{m_i})^{-1}),其中((frac{M}{m_i})^{-1})表示(frac{M}{m_i})(m_i)意义下的逆元

    如果求最小非负整数解,再模(M)即可

    证明

    对于每一个(x equiv a_i (mod m_i)),记解为(x_i),则有(x_i + m_i cdot y = a_i),两边除以(a_i),得:

    [frac{x_i}{a_i} + frac{m_i cdot y}{a_i} = 1 ag{1} ]

    (m_i)两两互质得(frac{M}{m_i})(m_i)互质,所以存在(p, q in Z^+),使得:

    [p cdot frac{M}{m_i} + q cdot m_i = 1 ag{2} ]

    即:

    [p cdot frac{M}{m_i} equiv 1 (mod m_i) \ p equiv (frac{M}{m_i})^{-1} (mod m_i) ag{3} ]

    ((1)(2)(3))易得(x_i = a_i cdot p cdot frac{M}{m_i} = a_i cdot frac{M}{m_i} cdot (frac{M}{m_i})^{-1})是方程的一个解

    对于(j eq i),有(m_j | frac{M}{m_i}),所以(x_i equiv 0 (mod m_j)),所以(sum_{i = 1}^{k} a_i cdot frac{M}{m_i} cdot (frac{M}{m_i}) ^ {-1} equiv a_j (mod m_j))

    故方程组的一个解是(x = sum_{i = 1}^{k} a_i cdot frac{M}{m_i} cdot (frac{M}{m_i}) ^ {-1}),显然(x \% M)是最小非负整数解

    一个应用

    有的时候题目要求答案模一个大合数,可以把合数拆成(prod p_{i}^{k_i})的形式,化成由(ans equiv a_i (mod p_{i}^{k_i}))组成的方程组然后求解

    代码

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    typedef long long LL;
    LL a[1005], m[1005], M = 1, ans;
    int n;
    
    void ExGCD(LL a, LL b, LL &d, LL &x, LL &y)
    {
    	if(!b) d = a, x = 1, y = 0;
    	else
    	{
    		ExGCD(b, a % b, d, y, x);
    		y -= a / b * x;
    	}
    }
    LL Inverse(LL a, LL p)
    {
    	LL x, y, d;
    	ExGCD(a, p, d, x, y);
    	x = (x % p + p) % p;
    	return x;
    }
    int main()
    {
    	scanf("%d", &n);
    	for(int i = 0; i < n; i++)
    		scanf("%lld", a + i);
    	for(int i = 0; i < n; i++)
    	{
    		scanf("%lld", m + i);
    		M *= m[i];
    	}
    	for(int i = 0; i < n; i++)
    		ans = (ans + M / m[i] * Inverse(M / m[i], m[i]) % M * a[i] % M) % M;
    	ans = (ans + M) % M;
    	printf("%lld
    ", ans);
    
    	return 0;
    }//Rhein_E
    
  • 相关阅读:
    How to Start Up an Open Source Company
    How Open Source Became The Default Business Model For Software
    Refactoring open source business models
    Open Source Isn't A Business Model, It's A Market Strategy
    11 open source business models
    5 Successful Business Models for Web-Based Open-Source Projects
    35 Top Open Source Companies
    golang实现php里的serialize()和unserialize()序列和反序列方法
    Laravel修炼:服务提供者
    使用 swoole_process 实现 PHP 进程池
  • 原文地址:https://www.cnblogs.com/Rhein-E/p/10637099.html
Copyright © 2011-2022 走看看