C. Lucky Days 题解(cf)(裴蜀定理思想)

版权声明:转载注明下出处就行了。 https://blog.csdn.net/LJD201724114126/article/details/84137089

题目链接:bang

题意:给出两组 l, r,t 表示 在区间 [ l+k*t , r+k*t ] (k属于非负整数)内是幸运的,问两组最多连续幸运天数是多少天?

先给出裴蜀定理的概念,参考百度百科。

对任意两个整数a、b设d是它们的最大公约数。那么关于未知数x和y的线性丢番图方程(称为裴蜀等式):

ax + by = m

有整数解(x,y)当且仅当m是d的倍数。裴蜀等式有解时必然有无穷多个解。

我们可以用拓展欧几里得求整数解(x,y)。

题解:要想使两组连续幸运天数尽可能的多,那就要想办法两组幸运区间要尽量对齐,那么我们就以右边界尽量对齐为基准,

给出两个区间 [la,ra] [lb,rb] (设ra<rb),gcd=gcd(ta,tb),我们要让ra靠近rb,只需将ra加上 m*gcd (m=(rb-ra)/gcd),相应的la也是加上同样的。为什么可以这样直接加呢?按道理不是应该加上 ta*k的吗?不急,我先给个样例:

4 6 12 和 11 13 18 ,按上面的方法,gcd=6,m=1,那么第一个区间靠近第二个区间就差6了,第一个区间加完(13-6)/6*6=6后就变成 [10,12] ,那么此时连续天数是2天,咦?

怎么能加6呢?应该是加12*k的啊?我来解释一下,第一个区间加完后[10,12]与第二个区间[11,13]的状态一定会存在,状态如下图所示:

  就是说会在之后的某个区间,这里其实就是 [64,66](12*5)(加的值) 和 [65,67] (18*3)这两个区间,而这里12*5-18*3=6的,刚好是我们把第一个区间[4,6]变成[10,12]的m*gcd=6的值,那么这说明上面的方法是正确的。其实也就是看看 12*x+18*y=6 有没有整数解,因为 gcd(12,18)|6,根据裴蜀定理一定有整数解。所以以后我们只需加上m*gcd就行了,因为ta*x+tb*y=m*gcd,而gcd(ta,tb)|m*gcd,故一定有整数解。

代码参考链接如下:https://blog.csdn.net/SwustLpf/article/details/84064459

#include<cstring>
#include<algorithm>
#include<cstdio>

using namespace std;

int gcd(int a,int b)
{
    if(!b) return a;
    else return gcd(b,a%b);
}

int solve(int a,int b,int x,int y){ ///计算两个区间公共的数

    return min(b,y)-max(a,x)+1;
}

int main()
{
    int la,ra,ta,lb,rb,tb;

    while(~scanf("%d%d%d%d%d%d",&la,&ra,&ta,&lb,&rb,&tb))
    {

        la++,ra++,lb++,rb++;

        int item=gcd(ta,tb); 

        if(ta==tb){ ///两个区间已经最靠近了,故直接算就行了
            printf("%d\n",solve(la,ra,lb,rb));
            continue;
        }
        int m,ans;
        if(ra<=rb){
             m=(rb-ra)/item;
            la+=m*item;
            ra+=m*item;
             ans=0; ///注意此处初始化为0,
             
///因为我们加的不一定刚好对齐,只需在不超过(尽量靠近)另一个区间和超过(尽量靠近)另一个区间之间选一个最大值就好了
            
            ans=max(ans,solve(la,ra,lb,rb)); 

            ans=max(ans,solve(la+item,ra+item,lb,rb));
        }
        else{
             m=(ra-rb)/item;
            lb+=m*item;
            rb+=m*item;
             ans=0;

            ans=max(ans,solve(la,ra,lb,rb));

            ans=max(ans,solve(la,ra,lb+item,rb+item));
        }

        printf("%d\n",ans);
    }
}

猜你喜欢

转载自blog.csdn.net/LJD201724114126/article/details/84137089