萌新求助EXCRT!!
查看原帖
萌新求助EXCRT!!
519384
Link_Cut_Y楼主2022/7/21 14:11

大概是因为判断无解出的问题,然鹅调了5个小时没有什么头绪。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <set>
#define int long long

using namespace std;

typedef long long LL;

const int N = 100010, M = 100010;
int T, n, m;
long long d[N], c[N + M], r[N];

namespace functions
{
	LL mul(LL a, LL b, LL p) { // 龟速乘 
		if (b < 0) a = -a, b = -b;
		LL res = 0;
		while (b)
		{
			if (b & 1) res = (res + a) % p;
			a = a * 2 % p;
			b >>= 1;
		}
		return res;
	}
	
	void exgcd(LL a, LL b, LL &x, LL &y) { // 扩欧 
		if (!b) {
			x = 1, y = 0;
			return;
		}
		exgcd(b, a % b, y, x);
		y -= (a / b) * x;
	}
	
	LL gcd(LL a, LL b) { return !b ? a : gcd(b, a % b); } // 最大公约数 
	LL lcm(LL a, LL b) { return a / gcd(a, b) * b; } // 最小公倍数 
	void equiv(LL a, LL b, LL &x, LL &y, LL c) // 求解 ax + by = c 
	{
		exgcd(a, b, x, y);
		LL g = gcd(a, b);
		x = x / g * c, y = y / g * c;
	}
}
using namespace functions;

multiset<long long> S;

signed main()
{
	freopen("P4774_5.in", "r", stdin);
//	freopen("ans.out", "w", stdout);
	
	scanf("%d", &T);
	
	while (T -- )
	{
		bool sp = true;
		S.clear();
		// INPUT
		scanf("%d%d", &n, &m);
		for (int i = 1; i <= n; i ++ )
			scanf("%lld", &d[i]);
		for (int i = 1; i <= n; i ++ ) {
			scanf("%lld", &r[i]);
			if (r[i] != 1) sp = false;
		}
		for (int i = m + 1; i <= m + n; i ++ )
			scanf("%lld", &c[i]);
		for (int i = 1; i <= m; i ++ )
			scanf("%lld", &c[i]), S.insert(c[i]);
		
		// METHODS
		if (sp) {
			LL ans = -2e9;
			for (int i = 1; i <= n; i ++ ) // 特判 
			{
				int s = d[i], p = r[i], a; // 第 i 条巨龙的初始生命值和恢复系数 
				multiset<long long>::iterator it = S.upper_bound(s);
				if (it == S.begin()) a = *it;
				else -- it, a = *it;
				S.erase(it);
				
				ans = max(ans, (LL)ceil((s + a - 1) / a));
				
				S.insert(c[i + m]);
			}
			cout << (long long)ans << endl;
			continue;
		}
		LL P = 1, x = 0;
		bool flag = false;
		for (int i = 1; i <= n; i ++ )
		{
			long long s = d[i], p = r[i], a; // 第 i 条巨龙的初始生命值和恢复系数 
			multiset<long long>::iterator it = S.upper_bound(s);
			if (it == S.begin()) a = *it;
			else -- it, a = *it;
			S.erase(it);
			
			LL y, k;
			exgcd(P * a, p, y, k);
			LL g = gcd(P * a, p);

			if((s - a * x) % g) { // 无解 
				puts("-1");
				flag = true;
				break;
			}
// 			y = (y * (s - a * x) / g % (p / g) + (p / g)) % (p / g), k = k * (s - a * x) / g;
			y = (mul(y, (s - a * x) / g, (p / g)) + (p / g)) % (p / g);
			x = x + (mul(y, P, p / g * P));
			P = lcm(P, p);
			x = (x % P + P) % P;
			S.insert(c[m + i]);
		}
		if(!flag) cout << (long long)((x % P + P) % P) << endl;
	}
	
	return 0;
}
2022/7/21 14:11
加载中...