Problem J. Modified LCS【扩展欧几里得】

在这里插入图片描述


题意

  • 给两个等差数列的长度,起点和数列的添加值,求两个数列中有几个数相同

题解

  • 将等差数列的通项公式化简后能够得到扩展欧几里得的结构,直接计算就可以
  • 假设 F 1 + K 1 ∗ D 1 = F 2 + K 2 ∗ D 2 F1+K1*D1 = F2+K2*D2 F1+K1D1=F2+K2D2 是某一个交点, 移向得到 F 1 − F 2 = K 2 ∗ D 2 − K 1 ∗ D 1 F1 - F2 = K2*D2 - K1*D1 F1F2=K2D2K1D1。 由扩展欧几里得定理的结论 x ∗ a + y ∗ b = K ∗ g c d ( a , b ) 。 x*a + y*b = K*gcd(a, b)。 xa+yb=Kgcd(a,b)
    所以 只有 F 1 − F 2 = K ∗ g c d ( D 1 , D 2 ) F1-F2 = K*gcd(D1, D2) F1F2=Kgcd(D1,D2) 时 才存在交点。

AC-Code

#include <bits/stdc++.h>
using namespace std;

ll exgcd(ll a, ll b, ll& x, ll& y)//扩展欧几里得算法
{
	if (b == 0) {
		x = 1; y = 0;
		return a;  //到达递归边界开始向上一层返回
	}
	ll r = exgcd(b, a % b, x, y);
	ll temp = y;    //把x y变成上一层的
	y = x - (a / b) * y;
	x = temp;
	return r;     //得到a b的最大公因数
}

int main() {
	int T;	cin >> T;
	while (T--) {
		ll n1, f1, d1, n2, f2, d2;	cin >> n1 >> f1 >> d1 >> n2 >> f2 >> d2;
		ll f = f2 - f1;
		ll x0, y0, gcd_ = exgcd(d1, -d2, x0, y0);
		if (f % gcd_) {
			cout << 0 << endl;  continue;
		}
		ll r = abs((-d2) / gcd_);
		ll x = (x0 * f / gcd_ % r + r) % r;
		ll y = (f - x * d1) / (-d2);
		ll dx = abs(d1 / gcd_);
		ll dy = abs(d2 / gcd_);
		ll ans = min((n1 - x - 1) / dy, (n2 - y - 1) / dx) + 1;
		cout << ans << endl;
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值