fastle
垆边人似月 皓腕凝霜雪
/*
首先杀每条龙用到的刀是能够确定的, 然后我们便得到了许多形如 ai - x * atki | pi的方程
而且限制了x的最小值

那么exgcd解出来就好了

之后就是扩展crt合并了 

因为全T调了一个小时 结果是没加文件?? 
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<set>
#include<iostream>
#define ll long long 
#define M 100010
#define mmp make_pair
using namespace std;
ll read()
{
	ll nm = 0, f = 1;
	char c = getchar();
	for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
	for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
	return nm * f;
}
ll n, q, a[M], m[M], p[M], g[M], atk[M], tp, maxx;
multiset<ll> st;
ll mul(ll a, ll b, ll mod)
{
	b = (b % mod + mod) % mod;
	ll ans = 0, tmp = a;
	for(; b; b >>= 1, tmp = (tmp + tmp) % mod) if(b & 1) ans = (ans + tmp) % mod;
	return ans;
}
ll gcd(ll a, ll b)
{
	return !b ? a : gcd(b, a % b);
}

ll exgcd(ll a, ll b, ll &x, ll &y)
{
	if(!b)
	{
		x = 1, y = 0;
		return a;
	}
	else
	{
		ll d = exgcd(b, a % b, x, y);
		ll tmp = x;
		x = y, y = tmp - a / b * y;
		return d;
	}
}

ll inv(ll a, ll p)
{
	ll x, y;
	ll d = exgcd(a, p, x, y);
	if(d != 1) return -1;
	return (x % p + p) % p;
}

void init()
{
	st.clear();
	tp = maxx = 0;
	n = read(), q = read();
	for(int i = 1; i <= n; i++) a[i] = read();
	for(int i = 1; i <= n; i++) p[i] = read();
	for(int i = 1; i <= n; i++) g[i] = read();
	for(int i = 1; i <= q; i++) st.insert(read());
	for(int i = 1; i <= n; i++)
	{
		multiset<ll>::iterator it = st.upper_bound(a[i]);
		if(it != st.begin()) it--;
		atk[i] = *it;
		st.erase(it);
		st.insert(g[i]);
	}
}

ll excrt()
{
	ll a1 = a[1], m1 = m[1], a2, m2;
	if(tp == 0)
	{
		a1 = 0;
	}
	else
	{
		for(int i = 2; i <= tp; i++)
		{
			a2 = a[i], m2 = m[i];
			ll d = gcd(m1, m2);
			ll c = a2 - a1;
			if(c % d) return -1;
			ll k = inv(m1 / d, m2 / d);
			m2 = m1 / d * m2;
			a1 = mul(mul(m1 / d, c, m2), k, m2) + a1;
			a1 %= m2;
			m1 = m2;
		}
	}
	return max(a1, maxx);
}	

void cz(int i)
{
	// a[i] - x * atk[i] + k * pi = 0
	// a[i] = x * atk[i] - k * p[i]
	// x * atk[i] = a[i]    mod p[i]
	//先处理gcd, 然后处理逆元
	if(p[i] == 1)
	{
		maxx = max(maxx, (a[i] + atk[i] - 1) / atk[i]);
	}
	else
	{
		tp++;
		ll gcdd = gcd(atk[i], p[i]);
		if(a[i] % gcdd)
		{
			a[tp] = -1;
		}
		else
		{
			atk[i] /= gcdd, p[i] /= gcdd;
			a[i] /= gcdd;
			a[tp] = mul(a[i], inv(atk[i], p[i]), p[i]);
			m[tp] = p[i];
		}
	}
}

void work()
{
	for(int i = 1; i <= n; i++)
	{
		cz(i);
		if(a[tp] == -1)
		{
			puts("-1");
			return;
		}
	}
	cout << excrt() << "\n"; 
} 

int main()
{
	freopen("dragon.in", "r", stdin);
	freopen("dragon.out", "w", stdout); 
	//freopen("dragon1.in", "r", stdin);
	int t = read();
	while(t--)
	{
		init();
		work();
	}
	return 0;
}

posted on 2019-04-09 08:57  fastle  阅读(82)  评论(0编辑  收藏  举报