一本通1635【例 5】Strange Way to Express Integers

1635:【例 5】Strange Way to Express Integers

 

 

sol:貌似就是曹冲养猪的加强版,初看感觉非常没有思路,经过一番艰辛的***,得到以下的结果

随便解释下给以后的自己听:K是要求的数字

第一个读入的A1,Mod1不用改,从2开始做,把Mod2改成LCM,A2改成Ans,接着搞3

/*
原式:
X = A[1] (%Mod[1])
X = A[2] (%Mod[2])
...
X = A[n] (%Mod[n])

K[1]*Mod[1]+A[1] = X
K[2]*Mod[2]+A[2] = X

易知: 
K[1]*Mod[1]+A[1] = K[2]*Mod[2]+A[2]
K[1]*Mod[1]-K[2]*Mod[2] = A[2]-A[1]
K[1]*Mod[1]+K[2]*Mod[2] = A[2]-A[1] (类ax+by=c的形式)
Exgcd解上式得到
Ans = K[1]*Mod[1]+A[1] = K[2]*Mod[2]+A[2](这是这个方程的特解)
通解 = Ans+KL*LCM(Mod[1],Mod[2])
易知通解P 满足 P%Mod[1] = A[1] , P%Mod[2] = A[2]
然后可得合并后的式子 P%LCM = Ans
下一个式子就变成了
KL*LCM+Ans = K[3]*Mod[3]+A[3]
KL*LCM-K[3]*Mod[3] = A[3]-Ans
(就是把前一个的Mod[i]变为LCM,A[i]变成Ans)
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read()
{
    ll s=0;
    bool f=0;
    char ch=' ';
    while(!isdigit(ch))
    {
        f|=(ch=='-'); ch=getchar();
    }
    while(isdigit(ch))
    {
        s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
    }
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0)
    {
        putchar('-'); x=-x;
    }
    if(x<10)
    {
        putchar(x+'0'); return;
    }
    write(x/10);
    putchar((x%10)+'0');
    return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const ll N=100005;
int n;
ll A[N],Mod[N];
inline ll gcd(ll x,ll y)
{
    return (!y)?(x):(gcd(y,x%y));
}
inline void Exgcd(ll a,ll b,ll &X,ll &Y)
{
    if(b==0)
    {
        X=1;
        Y=0;
        return;
    }
    Exgcd(b,a%b,X,Y);
    ll XX=X,YY=Y;
    X=YY;
    Y=XX-a/b*YY;
    return;
}
inline ll Solve()
{
    int i;
    ll a,b,c,r,X,Y,LCM=Mod[1],Ans=A[1];
    for(i=2;i<=n;i++)
    {
        a=Mod[i-1];
        b=Mod[i];
        c=A[i]-A[i-1];
        r=gcd(a,b);
        if(c%r) return -1;
        
        Exgcd(a,b,X=0,Y=0);
        X=X*c/r;
        ll tmp=b/r;
        X=(X>=0)?(X%tmp):(X%tmp+tmp);
        
        LCM=LCM*b/r;
        Mod[i]=LCM;
        Ans=X*Mod[i-1]+A[i-1];
        Ans%=LCM;
        A[i]=Ans;
    }
    return Ans;
}
int main()
{
//    freopen("2.in","r",stdin);
//    freopen("my.out","w",stdout);
    int i;
    while(~scanf("%d",&n))
    {
        for(i=1;i<=n;i++)
        {
            R(Mod[i]); R(A[i]);
        }
        Wl(Solve());
    }
    return 0;
}
/*
input
2
8 7
11 9
output
31

input
3
91 26
62 49
95 80
3
23 9
89 80
72 15
output
409435
36303
*/
View Code

 

posted @ 2019-03-03 17:24  yccdu  阅读(327)  评论(0编辑  收藏  举报