CF1055C Solution
题解
易得,左端点或右端点对齐时重叠部分一定是最大的。
可以发现,一定可以通过\(+k\cdot 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)=k\cdot 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;
}