[Codeforces710D]Two Arithmetic Progressions(扩展中国剩余定理)

题目描述

传送门

题解

x=a1k+b1,y=a2l+b2
也就是说
xb1(moda1)
xb2(moda2)
将两个方程用扩展中国剩余定理合并一下求出x
然后计算一下在[L,R]内的合法解个数就行了
还有一个需要注意的是 k,l0
也就是说 xmax(b1,b2)
所以要将L更新一下

代码

#include
#include
#include
#include
#include
using namespace std;
#define LL long long

LL m1,m2,c1,c2,L,R,c,m,t,ans;

LL gcd(LL a,LL b)
{
    if (!b) return a;
    else return gcd(b,a%b);
}
void exgcd(LL a,LL b,LL &x,LL &y)
{
    if (!b) x=1,y=0;
    else exgcd(b,a%b,y,x),y-=a/b*x;
}
LL inv(LL a,LL b)
{
    LL x=0,y=0;
    exgcd(a,b,x,y);
    x=(x%b+b)%b;
    if (!x) x+=b;
    return x;
}
int main()
{
    scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&m1,&c1,&m2,&c2,&L,&R);
    L=max(L,max(c1,c2));
    if (L>R)
    {
        puts("0");
        return 0;
    }
    c1%=m1,c2%=m2;
    t=gcd(m1,m2);
    if ((c2-c1)%t)
    {
        puts("0");
        return 0;
    }
    m=m1*m2/t;
    c=(inv(m1/t,m2/t)*((c2-c1)/t))%(m2/t)*m1+c1;
    c%=m;
    if (c>R)
    {
        ans=(c-R)/m-(c-L)/m;
        if ((c-R)%m==0) ++ans;
    }
    else if (cm-(L-c)/m;
        if ((L-c)%m==0) ++ans;
    }
    else ans=(R-c)/m+(c-L)/m+1;
    printf("%I64d\n",ans);
}

你可能感兴趣的:(题解,中国剩余定理)