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;
}
posted @ 2021-01-26 21:16  violet_holmes  阅读(98)  评论(0编辑  收藏  举报