欧几里得扩展应用

来源:互联网 发布:淘宝卖家手机号采集 编辑:程序博客网 时间:2024/06/14 07:25

X问题 HDU - 1573& Strange Way to Express Integers POJ - 2891

1. 题意

  1. 一个数模mi 等于 ai,第一个问题是求最小的,第二个问题是求x<=n有多少个

2. 分析

合并两个模数
假设
         y=a1(mod m1)
         y=a2(mod m2)
则有
         xa1+t1m1(mod m1);1
         xa2+t2m2(mod m2);2
         t1m1t2m2=a1a2
        利用欧几里得扩展求出 t1带入1 求出x

y=x(mod lcm(m1,m2))

3.参考代码

X问题 HDU - 1573

const int maxn = 100;int aa[maxn];int bb[maxn];int N,M;int  ex_gcd(int a,int b,int  &x,int  &y){    if(b==0)    {        x = 1;        y = 0;        return a;    }    LL c = ex_gcd(b,a%b,y,x);    y -= a/b*x;    return c;}int main(void){    int T;    cin>>T;    while(T--)    {        cin>>N>>M;        int A,B;        for(int i = 0; i < M; ++i)            cin>>aa[i];        for(int i = 0;i < M; ++i)            cin>>bb[i];        A = aa[0];        B = bb[0];        bool F = true;        for(int i = 1; i < M; ++i)        {            int  x,y;            int d = ex_gcd(A,aa[i],x,y);            int c = bb[i] - B;            if(c%d!=0)            {                F = false;                break;            }            c /= d;            x *= c;            aa[i] /= d;            x = (x%aa[i]+aa[i])%aa[i];            B = B + x * A;            A = A*aa[i];            B = (B%A+A)%A;        }        if(!F)            cout<<0<<endl;        else        {            if(B==0)                cout<<N/A<<endl;            else                cout<< N/A+((N-N/A*A)>=B?1:0)<<endl;        }    }}

Strange Way to Express Integers POJ - 2891

using namespace std;long long exgcd(long long m,long long n,long long &x,long long &y){    long long x1,y1,x0,y0;    x0=1; y0=0;    x1=0; y1=1;    x=0; y=1;    long long r=m%n;    long long q=(m-r)/n;    while(r)    {        x=x0-q*x1; y=y0-q*y1;        x0=x1; y0=y1;        x1=x; y1=y;        m=n; n=r; r=m%n;        q=(m-r)/n;    }    return n;}int main(){    int n;    long long a1,r1,a2,r2,c,d,x,y;    bool flat;    while(scanf("%d",&n)!=EOF)    {        flat=false;        scanf("%lld%lld",&a1,&r1);        for(int i=1;i<n;i++)        {            scanf("%lld%lld",&a2,&r2);            if(flat)continue;            c=r2-r1;            d=exgcd(a1,a2,x,y);            if(c%d)            {                flat=true;                continue;            }            x*=c/d;            a2/=d;            x=(x%a2+a2)%a2;            r1=r1+x*a1;            a1*=a2;        }        if(flat)puts("-1");        else printf("%lld\n",r1);    }    return 0;    }
原创粉丝点击