题解
易得,左端点或右端点对齐时重叠部分一定是最大的。
可以发现,一定可以通过(+kcdot gcd(t_a,t_b))将左区间尽量右移直至差值(le gcd(t_a,t_b))。证明:根据裴蜀定理——若(a,b)是整数,且(d|gcd(a,b)),一定存在整数(x,y),使(ax+by=d)成立。一定存在(x,y)使得(t_ax-t_by(或t_bx-t_ay)=kcdot gcd(t_a,t_b))。
此外,还需分类讨论(a,b)的左右顺序,以及左区间是否超过右区间。
AC代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int Gcd(int a,int b) {return (!b)?a:Gcd(b,a%b);}
int val(int l1,int l2,int r1,int r2,int t)
{
l1+=t; r1+=t;
return min(r1,r2)-max(l1,l2)+1;
}//计算重叠部分长度
signed main()
{
int la,lb,ra,rb,ta,tb;
scanf("%lld%lld%lld%lld%lld%lld",&la,&ra,&ta,&lb,&rb,&tb);
//因为可能会出现0影响计算,l,r全部+1
la++; ra++;
lb++; rb++;
int gcd=Gcd(ta,tb),add=abs(ra-rb)/gcd*gcd,ans=0;//add:题解中的k·gcd(ta,tb)
//1:a在前且不超过右区间,2:a在前且超过右区间
ans=max(ans,max(val(la,lb,ra,rb,add)/*1*/,val(la,lb,ra,rb,add+gcd)/*2*/));
//1:b在前且不超过右区间,2:b在前且超过右区间
ans=max(ans,max(val(lb,la,rb,ra,add)/*3*/,val(lb,la,rb,ra,add+gcd)/*4*/));
printf("%lld",ans);
return 0;
}