首页 > 代码库 > HDU 1573: X问题

HDU 1573: X问题

X问题

 

///@author Sycamore, ZJNU;
///@date 8/4/2017
///@ref stanford-acm-master
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
typedef pair<int, int>PII;
typedef vector<int> VI;
// return a % b (non-negative value)
int mod(int a, int b)
{
	return ((a%b) + b) % b;
}
 
// returns g = gcd(a, b); finds x, y such that d = ax + by
int extended_euclid(int a, int b, int &x, int &y)
{
	int xx = y = 0;
	int yy = x = 1;
	while (b)
	{
		int q = a / b;
		int t = b;
		b = a%b;
		a = t;
		t = xx;
		xx = x - q*xx;
		x = t;
		t = yy;
		yy = y - q*yy;
		y = t;
	}
	return a;
}
// Chinese remainder theorem (special case): find z such that
// z % m1 = r1, z % m2 = r2. Here, z is unique modulo M = lcm(m1, m2).
// Return (z, M). On failure, M = -1.
 
 
PII chinese_remainder_theorem(int m1, int r1, int m2, int r2)
{
	int s, t;
	int g = extended_euclid(m1, m2, s, t);
	if (r1%g != r2%g) return make_pair(0, -1);
	return make_pair(mod(s*r2*m1 + t*r1*m2, m1*m2) / g, m1*m2 / g);
}
// Chinese remainder theorem: find z such that
// z % m[i] = r[i] for all i. Note that the solution is
// unique modulo M = lcm_i (m[i]). Return (z, M). On
// failure, M = -1. Note that we do not require the a[i]s
// to be relatively prime.
PII chinese_remainder_theorem(const VI &m, const VI &r)
{
	PII ret = make_pair(r[0], m[0]);
	for (int i = 1; i < m.size(); i++)
	{
		ret = chinese_remainder_theorem(ret.second, ret.first, m[i], r[i]);
		if (ret.second == -1) break;
	}
	return ret;
}
 
int main()
{
	ios::sync_with_stdio(false);
	int T;
	cin >> T;
	while (T--)
	{
		int N, M;
		cin >> N >> M;
		vector<int>A(M), B(M);
		for (auto &e : A)cin >> e;
		for (auto &e : B)cin >> e;
		auto result = chinese_remainder_theorem(A, B);
		//X=X0+k*lcm
		if (~result.second&&result.first <= N)
		{
			int ans = (N - result.first) / result.second + 1;
			if (result.first%result.second == 0)ans = max(0, ans - 1);
			cout << ans << ‘\n‘;
		}
 
		else
			cout << "0\n";
	}
	return 0;
}

HDU 1573: X问题