缺氧

2015/12/03 Go the extra mile.

cf/Codeforces ECR16-D - Two Arithmetic Progressions-中国剩余定理

Problem ECR16-D - Two Arithmetic Progressions-

题目大意

 给两个等差数列 You are given two arithmetic progressions: a1k + b1 and a2l + b2. Find the number of integers x such that L ≤ x ≤ R andx = a1k' + b1 = a2l' + b2, for some integers k', l' ≥ 0.  

给一个L,R,问L到R里有多少个x满足  x = a1k' + b1 = a2l' + b2,

   数据范围:a1,a2,b1,b2,L,R <= 10^18。

解题分析

   其实题目的式子可以转化为两个模仿方程,也就是 x=b1(mod a1 )  ,x=b2(mod a2 )

由于a1,a2并不互质,不能直接用中国剩余定理,我们需要通过把式子都合并起来,再使用中国剩余定理

  如果两个式子不能合并,那么就是找不到x,输出0,否则就找一个比L小的 正解cur,然后看看cur到L-1里有多少个解,cur到R里有多少个解。


由于题目的直线斜率是正的,因此 x的最小取值为max(b1,b2),L取max(L,max(b1,b2))

 


参考程序


 

#include <iostream>
#include <string.h>
#include <stdio.h>

using namespace std;
typedef long long ll;
const int N = 1005;

ll a[N], m[N];

ll gcd(ll a,ll b)
{
    return b? gcd(b, a % b) : a;
}

void extend_Euclid(ll a, ll b, ll &x, ll &y)
{
    if(b == 0)
    {
        x = 1;
        y = 0;
        return;
    }
    extend_Euclid(b, a % b, x, y);
    ll tmp = x;
    x = y;
    y = tmp - (a / b) * y;
}

ll Inv(ll a, ll b)
{
    ll d = gcd(a, b);
    if(d != 1) return -1;
    ll x, y;
    extend_Euclid(a, b, x, y);
    return (x % b + b) % b;
}

bool merge(ll a1, ll m1, ll a2, ll m2, ll &a3, ll &m3)
{
    ll d = gcd(m1, m2);
    ll c = a2 - a1;
    if(c % d) return false;
    c = (c % m2 + m2) % m2;
    m1 /= d;
    m2 /= d;
    c /= d;
    c *= Inv(m1, m2);
    c %= m2;
    c *= m1 * d;
    c += a1;
    m3 = m1 * m2 * d;
    a3 = (c % m3 + m3) % m3;
    return true;
}
ll cur,mm;
ll CRT(ll a[], ll m[], int n)
{
    ll a1 = a[1];
    ll m1 = m[1];
    for(int i=2; i<=n; i++)
    {
        ll a2 = a[i];
        ll m2 = m[i];
        ll m3, a3;
        if(!merge(a1, m1, a2, m2, a3, m3))
            return -1;
        a1 = a3;
        m1 = m3;
    }
    cur=a1,mm=m1;
    return (a1 % m1 + m1) % m1;
}

int main()
{
    int n=2;
    ll L,R;
    for(int i=1; i<=n; i++)
        scanf("%lld%lld",&m[i], &a[i]);
    scanf("%lld%lld",&L,&R);
    ll ans = CRT(a, m, n);
    if (ans==-1)
    {
        printf("0\n");
        return 0;
    }
    L=max(L,max(a[1],a[2]));        //***
    //cal ans between [L-1,R]
    ans=0;
    if (cur>=L) cur-=((cur-L)/mm+1)*mm;  //find a cur that < L
    if (L<=R)
        ans= (R-cur)/mm-(L-1-cur)/mm;

    printf("%lld\n",ans);

    return 0;
}

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/viphong/article/details/52382105
上一篇cf/codeforces#369-E - ZS and The Birthday Paradox- 数学+gcd+逆元+勒让德定理
下一篇cf/codeforces #365 E - Mishka and Divisors 数学+背包dp+gcd
想对作者说点什么? 我来说一句

中国剩余定理

2008年01月10日 908B 下载

中国剩余定理仿真代码matlab

2014年11月04日 767B 下载

广义中国剩余定理及其Maple解法

2010年06月21日 137KB 下载

中国剩余定理python实现

2018年01月25日 23KB 下载

Arithmetic complexity of computations

2017年11月18日 27.18MB 下载

中国剩余定理——另一种证明

2008年06月16日 59KB 下载

没有更多推荐了,返回首页

关闭
关闭