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;
}

 

posted @ 2014-09-22 20:03  PlasticSpirit  阅读(216)  评论(0编辑  收藏  举报