CF710D Two Arithmetic Progressions

原题链接

即求在\([L,R]\)之间有多少个整数\(K\)满足\(K = a_1x + b_1 = a_2y + b_2\),其中\(x,y\)为自然数
很容易想到将等式移项,变为\(a_1x + a_2(-y) = b_2 - b_1\)
那么很明显可以用扩欧来求出一组\(x,y\)的特解,并将特解移至自然数范围内的最小解
因为原式是等式,接下来我们只需要关注其中一个解,例如\(x\)
设扩欧求出的\(x\)的通解为\(x_0 + k\times MOD\),其中\(MOD = a_2/gcd\),因为特解\(x_0\)是摸\(MOD\)下最小自然数解,所以\(k\)也为自然数
题目要求的是\([L,R]\)之间有多少个整数\(K\)满足\(K = a_1x + b_1\)
将通解代入,即求\([L,R]\)之间有多少个整数\(K\)满足\(K = (a_1MOD)k + a_1x_0 + b_1\)
那么最后就是求有多少\(k\)能让整数落于\([L,R]\),因为\(k\)连续,所以直接算不大于\(R\)的最大\(k\)和不小于\(L\)的最小\(k\)即可
写成公式就是\(\left\lfloor\dfrac{R - (a_1x_0 + b_1)}{a_1MOD}\right\rfloor - \left\lceil\dfrac{L - (a_1x_0 + b_1)}{a_1MOD}\right\rceil + 1\)
但要注意可能会除出来负数,因为\(k\)为自然数,要手动调到\(0\),具体见代码。

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const int mod = 1073741824;
inline ll re()
{
	ll x = 0;
	char c = getchar();
	bool p = 0;
	for (; c < '0' || c > '9'; c = getchar())
		p |= c == '-';
	for (; c >= '0' && c <= '9'; c = getchar())
		x = x * 10 + c - '0';
	return p ? -x : x;
}
ll exgcd(ll a, ll b, ll& x, ll& y)
{
	if (!b)
	{
		x = 1; y = 0;
		return a;
	}
	ll gcd = exgcd(b, a % b, y, x);
	y -= a / b * x;
	return gcd;
}
int main()
{
	ll i, j, k, n, m, a_1, a_2, b_1, b_2;
	a_1 = re(); b_1 = re(); a_2 = re();
	b_2 = re(); n = re(); m = re();
	ll x, y, gcd = exgcd(a_1, a_2, x, y);
	if ((b_2 - b_1) % gcd)//无解
		return printf("0"), 0;
	x *= (b_2 - b_1) / gcd;//一组特解
	y *= (b_2 - b_1) / gcd;
	ll MOD = a_2 / gcd;
	x = (x % MOD + MOD) % MOD;//先让x落于自然数范围
	y = -((b_2 - b_1) - a_1 * x) / a_2;//算出此时的y
	if (y < 0)//若y还是负数就让y落于自然数范围并计算出x,此时x一定为自然数
	{
		ll MODY = a_1 / gcd;
		y = (y % MODY + MODY) % MODY;
		x = ((b_2 - b_1) + a_2 * y) / a_1;
	}
	m = floor(1.0 * (m - a_1 * x - b_1) / (a_1 * MOD));//计算最大的k
	if (m < 0)//不大于右边界的最大k都为负,那么一定不存在解
		return printf("0"), 0;
	n = ceil(1.0 * (n - a_1 * x - b_1) / (a_1 * MOD));//计算最小的k
	if (n < 0) n = 0;//k不能小于0
	printf("%lld", m - n + 1);
	return 0;
}
上一篇:leetcode_1095. Find in Mountain Array_[Binary Search]


下一篇:linux - 启动solr 报错 Your Max Processes Limit is currently 31202. It should be set to 65000 to avoid