hdu1573:数论,线性同余方程组

题目大意:

给定一个N ,m

找到小于N的  对于i=1....m,满足  x mod ai=bi  的 x 的数量。

分析

先求出 同余方程组 的最小解x0,然后 每增加lcm(a1...,am)都会存在一个解,注意必须小于N 不能等于

代码:

#include <iostream>

#include <stdio.h>

#include<string.h>

#include<algorithm>

#include<string>

#include<ctype.h>

using namespace std;

#define MAXN 10000

int a[11];

int b[11];

int n,m;

int gcd(int a,int b)

{

    return b?gcd(b,a%b):a;

}

int lcm(int a,int b)

{

    return a*b/(gcd(a,b));

}

int exgcd(int a,int b,int &x,int &y)

{

    if(!b)

    {

        x=1;

        y=0;

        return a;

    }

    int tt=exgcd(b,a%b,x,y);

    int t;

    t=x;

    x=y;

    y=(t-a/b*y);

    return tt;

}

int solve()

{

    int a1,a2,b1,b2,x,y,A,B,C,d,t;

    a1=a[0];

    b1=b[0];

    for(int i=1;i<m;i++)

    {

        a2=a[i];

        b2=b[i];

        A=a1;

        B=a2;

        C=b2-b1;

        d=exgcd(A,B,x,y);

        if(C%d)

        {

            return -1;

        }

        t=B/d;

        x=(x*(C/d)%t+t)%t;

        b1=a1*x+b1;

        a1=a1/d*a2;

    }

    return b1;

}

int main()

{

    int t;

    scanf("%d",&t);

    while(t--)

    {

        scanf("%d%d",&n,&m);

        for(int i=0;i<m;i++)

        {

            scanf("%d",a+i);

        }

        for(int i=0;i<m;i++)

        {

            scanf("%d",b+i);

        }

        int lm=1;

        for(int i=0;i<m;i++)

        {

            lm=lcm(a[i],lm);

        }

        int ans=0;

        int tmp=solve();

        if(tmp==-1)

        {

            puts("0");

            continue;

        }

        if(tmp<=n)

            ans+=1+(n-tmp)/lm;

        if(ans&&tmp==0)

            ans--;

        cout<<ans<<endl;

    }

    return 0;

}

 

你可能感兴趣的:(HDU)