题意:
a君,b君存在幸运周期;
a君在第[L1+k*T1,R1+k*T1]天为幸运天;
b君在第[L2+k*T2,R2+k*T2]天为幸运天;
求a君,b君最大的连续的幸运天数;
题解:
a君所有幸运天数开始的时刻为 La = L1+X*T1;
b君所有幸运天数开始的时刻为 Lb = L2+Y*T2;
假设 a君每个周期幸运的天数为 lena , b君的为 lenb;
①如果∃X,Y使得 La = Lb ,那么答案就是 min(lena,lenb);
②反之,根据贪心策略,找到最小的非负整数 d1 使得 La + d1 = Lb 或最小的非负整数 d2 使得 La = Lb+d2;
两者取最大值;
如何判断①是否成立呢?
根据拓展欧几里得,使得①成立当且仅当 GCD(T1,T2) | abs(Lb-La);
如果不成立,如何找到最小的d1,d2呢?
令 gcd = GCD(T1,T2);
最小的非负整数 d1 = (L2-L1)%gcd(如果 d1 < 0 , d1 += gcd);
d2=gcd-d1;
分别求解即可;
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define INFll 0x3f3f3f3f3f3f3f3f 4 #define GCD(a,b) __gcd(a,b) 5 #define ll long long 6 7 struct Date 8 { 9 ll l,r,t; 10 ll len(){return r-l+1;}; 11 }a,b; 12 13 ll F(ll L1,ll R1,ll L2,ll R2) 14 { 15 return max(min(R1,R2)-max(L1,L2)+1,1ll*0)///答案有可能小于0,所以需要对0取个max; 16 } 17 ll Solve() 18 { 19 ll gcd=GCD(a.t,b.t); 20 ll c=abs(a.l-b.l); 21 if(c%gcd == 0)///情况① 22 return min(a.len(),b.len()); 23 ll d1=((b.l-a.l)%gcd+gcd)%gcd;///情况② 24 ll d2=gcd-d1; 25 /*****************La+d1=Lb******************La=Lb+d2*********/ 26 ll ans=max(F(0,a.r-a.l,d1,d1+b.r-b.l),F(0,b.r-b.l,d2,d2+a.r-a.l)); 27 return ans; 28 } 29 int main() 30 { 31 // freopen("C:\\Users\\hyacinthLJP\\Desktop\\in&&out\\contest","r",stdin); 32 scanf("%lld%lld%lld",&a.l,&a.r,&a.t); 33 scanf("%lld%lld%lld",&b.l,&b.r,&b.t); 34 printf("%lld\n",Solve()); 35 36 return 0; 37 }