hdu 1573 X问题 (线性同余方程组)

题意:求在小于等于N的正整数中有多少个X满足:X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], …, X mod a[i] = b[i], … (0 < a[i] <= 10)。

思路:运用我上一个博客的模板再加一个 性质—— 通解:X=X'+lcm(a[0],a[1]..a[i])*k (其中X'是该线性同余方程的最小非负整数解,k=0,1,2,3...),那么:ans = (N-X')/lcm+1,(ps:加1是因为k是从0开始的)注意当X'=0时 X=lcm*k(k=0,1,2..),由于题目要求小于等于N的正整数中有多少个X,这时ans = N/lcm;

代码:

#include <iostream>
#include <cstdio>
#define ll long long 

using namespace std;

ll gcd(ll a,ll b)
{
    if(b==0) return a;
    else return gcd(b,a%b);
}

ll lcm(ll a,ll b)
{
    return a*b/gcd(a,b);
}

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

ll solve(ll a[],ll r[],ll n)
{
    ll d,c,i,x,y,t;
    for(i=1;i<n;i++)
    {
        c=r[i]-r[i-1];
        d=exgcd(a[i-1],a[i],x,y);
        if(c%d!=0) return -1;
        t=a[i]/d;
        x=(x*(c/d)%t+t)%t;
        r[i]=a[i-1]*x+r[i-1];
        a[i]=a[i-1]*(a[i]/d);
    }
    return r[n-1];
}

int main() {
    int t;
    ll a[15];
    ll r[15];
    cin>>t;
    while(t--)
    {
        ll N,M;
        ll lcmm;
        scanf("%lld %lld",&N,&M);
        for(int i=0;i<M;i++)
        {
            scanf("%lld",&a[i]);
            if(i==0) lcmm=a[i];
            else lcmm=lcm(a[i],lcmm);
        }
        for(int i=0;i<M;i++)
        {
            scanf("%lld",&r[i]);
        }
        ll minn=solve(a,r,M);
        ll ans;
        if(minn==-1||minn>N) cout<<"0"<<endl;
        else
        {
            ans = (N-minn)/lcmm+1;
            if(minn==0) ans = N/lcmm;
            cout<<ans<<endl;
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/simplekinght/p/6818185.html