中国剩余定理(CRT)

原理及例题讨论
非质数取模参考
扩展中国剩余定理,使用非互质情况
如何利用中国剩余定理求解非质数取模即注意事项,以及为什么可以这样做?
例题

板子

互质板子

这里的u[]数组为模数数组

void exgcd(ll a,ll b,ll &x,ll &y)
    {
        if(!b){
            x = 1, y = 0;
            return;
        }
        exgcd(b, a % b, x, y);
        ll t = x;
        x = y, y = t - (a / b) * y;
    }

    ll gunc(vector<ll>&res){
        ll ans = 0;
        ll out = 1;
        for(int i = 0;i<3;i++){
            out = out*u[i];
        }
        for(int i = 0;i<3;i++){
            ll s = out/u[i];
            ll x = 0,y = 0;
            exgcd(s,u[i],x,y);
            if(x<0)
                x += u[i];
            ans += s*x*res[i];
        }
        ans = ans%out;
        return ans;
    }

非互质&互质共用板子

ll exgcd(ll a, ll b, ll &x, ll &y){
        if(b==0){
            x = 1, y = 0;
            return a;
        }
        ll d, x1, y1;
        d = exgcd(b, a%b, x1, y1);
        x = y1, y = x1 - a/b*y1;
        return d;
    }

    ll excrt(vector<ll>& m, vector<ll>& r){
        int n = m.size();
        ll m1, m2, r1, r2, p, q;
        m1 = m[0], r1 = r[0];
        for(int i = 1; i < n; ++i){
            m2 = m[i], r2 = r[i];
            ll d = exgcd(m1, m2, p, q);
            if( (r2-r1)%d !=0 ) return -1; // 不能整除,说明无解
            p = p*(r2-r1)/d;
            p = (p%(m2/d) + (m2/d))%(m2/d);
            r1 = m1*p+r1;
            m1 = m1*m2/d;
        }
        return (r1%m1+m1)%m1;
    }

你可能感兴趣的:(算法)