裴蜀定理CF1055C Lucky Days

Posted 行码棋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了裴蜀定理CF1055C Lucky Days相关的知识,希望对你有一定的参考价值。

Lucky Days

较好观感

给定 l a , r a , t a , l b , r b , t b l_a,r_a,t_a,l_b,r_b,t_b la,ra,ta,lb,rb,tb,对于所有的非负整数 k k k,将区间 [ l a + k t a , r a + k t a ] [l_a+kt_a,r_a+kt_a] [la+kta,ra+kta] 打上标记 1 1 1,将区间 [ l b + k t b , r b + k t b ] [l_b+kt_b,r_b+kt_b] [lb+ktb,rb+ktb] 打上标记 2 2 2。求出最长的连续区间使得该区间中的所有位置都被同时打上的 1 , 2 1,2 1,2 标记。

样例一

0 2 5
1 3 5
2

样例二

0 1 3
2 3 6
1


思路

题目要求两个区间的重合度最大的长度。

首先第一个点我们要想到:要想使两个区间的重合度最高,需要让两个区间尽可能逼近。最优的情况就是两个区间的左端点尽可能相等,这样重合度是最大的。

即使 l a + x ∗ t a = l b + y ∗ t b la + x * ta = lb + y * tb la+xta=lb+ytb

将式子进行移项得 x ∗ t a − y ∗ t b = l b − l a x * ta - y * tb = lb - la xtaytb=lbla (此时我们假设 l a < l b la < lb la<lb,代码中已做相关的操作,这样只是为了方便)

我们需要看式子是否有解,式子结构和裴蜀定理比较像,拿出来进行对比。

裴蜀定理 : 存在整数 x , y x, y x,y,满足 a ∗ x + b ∗ y = g c d ( a , b ) a * x + b * y = gcd(a,b) ax+by=gcd(a,b)

该式子进行 y y y符号变为正,表示 y y y是整数,则 x ∗ t a + y ∗ t b = l b − l a x * ta + y * tb = lb - la xta+ytb=lbla

我们令 d = g c d ( t a , t b ) d = gcd(ta, tb) d=gcd(ta,tb)

那么可以发现如果 d ∣ ( l b − l a ) d | (lb - la) d(lbla),则该式子有解,左端点可以重合。


但是如果左端点不能重合怎么办,尽可能逼近就行。

此时别忘了式子右边的 l b − l a lb-la lbla代表的是什么,是 区间a左端点移动的距离,那么因为 x ∗ t a + y ∗ t b = d x * ta + y * tb = d xta+ytb=d是存在解的,则区间a移动的距离可进一步变为 d d d

注意:我说的区间a可以移动,是指的一定存在某种状态,上下两个人有两个区间的距离发生了变化,叫为区间移动更容易理解。如

t a = 3 , [ 1 , 4 ] − > [ 4 , 7 ] − > [ 7 , 10 ] − > [ 10 , 13 ] ta = 3,[1,4]->[4,7]->[7,10]->[10,13] ta=3,[1,4]>[4,7]>[7,10]>[10,13]

t b = 4 , [ 3 , 5 ] − > [ 7 , 9 ] − > [ 11 , 13 ] tb = 4,[3,5]->[7,9]->[11,13] tb=4,[3,5]>[7,9]>[11,13]

[ 1 , 4 ] [ 3 , 5 ] [1,4][3,5] [1,4][3,5]左端点相差 2 2 2,这是一种区间状态,通过移动,会出现另一种区间状态 [ 10 , 13 ] [ 11 , 13 ] [10,13][11,13] [10,13][11,13]左端点相差 1 1 1。移动了一步( d = g c d ( 3 , 4 ) = 1 d = gcd(3,4) = 1 d=gcd(3,4)=1

左端点不重合就尽可能逼近。

有两种状态可能是合适的。

d i s dis dis代表a区间左端点与b区间左端点相差的最小距离(a区间左端点我认为小于等于b区间左端点),即 d i s = ( l b − l a ) % d dis = (lb - la) \\% d dis=(lbla)%d

  • 区间a左端点移动到和区间b左端点相差 ( l b − l a ) % d (lb-la) \\% d (lbla)%d,可能是距离最近的

    • m i n ( r b − l b + 1 , r a − l a + 1 − d i s ) min(rb - lb + 1, ra - la + 1 - dis) min(rblb+1,rala+1dis)
  • 然后是上面的情况在往后移一步,即区间a左端点超过区间b左端点 d − ( l b − l a ) d-(lb-la)%d d(lbla)

    • d i s = d − d i s dis = d - dis dis=ddis
    • m i n ( r a − l a + 1 , r b − l b + 1 − d i s ) min(ra - la + 1, rb - lb + 1 - dis) min(rala+1,rblb+1dis)

两个计算请画图领悟计算方法。

计算:左端点重合的情况可以合并在左端点能合并的代码里面,即左端点合并是左端点不合并的特殊情况。

代码

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int N = 1e5 + 5, mod = 1e9 + 7;

// [l[a] + k * ta, r[a] + k * ta]
// 3 [1, 4] [4, 7] [7, 10] [10, 13] [13, 16] ---
// 4 [3, 5] [7, 9] [11, 13]         [15, 17] ---
// 起点尽可能相同
// 裴蜀定理:存在x,y 使 ax + by = gcd(a, b)
// la + x * ta = lb + y * tb
// x * ta - y * tb = lb - la
// gcd(ta, tb) | (lb - la)有解
// d = gcd(ta, tb) 看成相对移动的距离
// la -> la + d -> la + k * d    lb
// 差 = lb - la 
// dis = (lb - la) % d

void solve()

	int la, ra, ta, lb, rb, tb;
	cin >> la >> ra >> ta >> lb >> rb >> tb;
	if(la > lb)
	
		swap(la, lb);
		swap(ra, rb);
		swap(ta, tb);
	
	int d = __gcd(ta, tb);
	int dis = (lb - la) % d; // 左端点的差
	int ans = 0;
	ans = max(ans, min(rb - lb + 1, ra - la + 1 - dis));
	dis = d - dis; // 向右移动一步
	ans = max(ans, min(ra - la + 1, rb - lb + 1 - dis));
	cout << ans << "\\n";

int main()

	ios::sync_with_stdio(false);
	cin.tie(0);

	int t;
	// cin >> t;以上是关于裴蜀定理CF1055C Lucky Days的主要内容,如果未能解决你的问题,请参考以下文章

裴蜀定理CF1055C Lucky Days

裴蜀定理CF1055C Lucky Days

D. Not Quite Lee(裴蜀定理gcdlowbit)

D. Not Quite Lee(裴蜀定理gcdlowbit)

D. Not Quite Lee(裴蜀定理gcdlowbit)

cf1011 E. Border