hdu 1573 X问题

来源:互联网 发布:mac禁止开机启动项 编辑:程序博客网 时间:2024/05/21 14:07
#include <iostream>#include <cstring>#include <cstdio>using namespace std;const int MAXN = 15;typedef long long LL;LL Gcd(LL a, LL b){    if(b == 0)        return a;    else        return Gcd(b, a%b);}void Ex_Gcd(LL a, LL b, LL &d, LL &x, LL &y){    if(b == 0)    {        d = a;        x = 1;        y = 0;        return ;    }    else    {        Ex_Gcd(b, a%b, d, x, y);        LL temp = x;        x = y;        y = temp - (a/b) * y;    }}int main(){    LL aa[MAXN], bb[MAXN];    LL n, a, b, c, d, x0, y0, lcm;    int T, m, i;    cin>>T;    while(T--)    {        cin>>n>>m;        bool flag = true;        lcm = 1;        for(i = 1; i <= m; ++i)        {            cin>>aa[i];            lcm = lcm / Gcd(lcm, aa[i]) * aa[i];        }        for(i = 1; i <= m; ++i)            cin>>bb[i];        for(i = 2; i <= m; ++i)//**        {            a = aa[1];            b = aa[i];            c = bb[i] - bb[1];            Ex_Gcd(a, b, d, x0, y0);            if(c % d != 0)            {                flag = false;                break;            }            LL t = b/d;            x0 = x0 * (c/d);            x0 = (x0 % t + t) % t;            bb[1] = aa[1] * x0 + bb[1];            aa[1] = aa[1] * (aa[i]/d);        }        if(!flag)        {            cout<<"0"<<endl;            continue;        }        LL ans = 0;        if(bb[1] <= n)            ans = 1 + (n - bb[1])/lcm;        if(ans && (bb[1] == 0))            ans--;        printf("%I64d\n", ans);    }    return 0;}


注:上面代码中带//**的for循环执行完后,aa[1] = lcm,rr[1]也是最后求得的最小正整数解,即:x0 = rr[1];并有x0 ≡ rr[1] (mod a[1]),等价于:x0 = rr[1] + aa[1] * k,其中k = 0。

    若有方程满足:x = rr[1] + aa[1]*k   ···(*),其中k ∈ Z,则有x ≡ rr[1] (mod a[1]),<等同于x ≡ rr[1] (mod lcm),因为aa[1] = lcm>。因此求小于N的正整数满足(*)式的x有多小个,也即是求k的值。

等于ans = (n-x0)/lcm + 1;加1是为了包含x0;

0 0
原创粉丝点击