POJ2891 Strange Way to Express Integers

来源:互联网 发布:软件应用的英文 编辑:程序博客网 时间:2024/06/05 23:06

题面

题意

给出n对数,每对数为k1,r1,已知m%k1=r1,求m.

方法

欧扩

在输入时,不断改变m的值使它符合条件,为使m也符合之前的条件,故只能加前面所有k的最小公倍数,顾可得如下方程:
ki*x+ri=m(之前)+gcd(k[i-1]……..k[1]) *y.
移项后得ki*x-gcd(….) *y=m-ri.
此方程可用欧扩来解

代码

#include<iostream>#include<cstdio>#define ll long longusing namespace std;ll n,ans,k,g,a,b,c,x,y,move,fh1[]={1,1,-1,-1},fh2[]={1,-1,1,-1};bool P;ll abs(ll u){    return u>0?u:-u;}ll gcd(ll u,ll v){    while(u!=v&&u&&v)    {        if(u>v) u%=v;        else v%=u;    }    return max(u,v);}ll ny(ll u,ll v){    if(v)    {        ll p=ny(v,u%v);        x-=(u/v)*y;        swap(x,y);        return p;    }    else    {        x=1;        y=0;        return u;    }}int main(){    ll i,j,p,q;    while(~scanf("%lld%lld%lld",&n,&k,&ans))    {        P=1;        for(i=2;i<=n;i++)        {            scanf("%lld%lld",&p,&q);            if(!P) continue;            a=p;            b=k;            c=ans-q;            g=gcd(a,b);            if(c%g!=0)            {                P=0;                continue;            }            ny(a,b);            x*=c/g;            y*=c/g;//          cout<<a<<" "<<b<<" "<<c<<endl;//          cout<<x<<" "<<y<<endl;            move=b/g;//          cout<<x<<" "<<move<<" ";            x=(x%move+move)%move;            k*=p/gcd(k,p);//          cout<<x;            ans=p*x+q;        }        if(P) printf("%lld\n",ans);        else printf("-1\n");    }}
阅读全文
1 0
原创粉丝点击