只过了p_i=1的情况,30pts求调
查看原帖
只过了p_i=1的情况,30pts求调
848964
hzoi_Shadow楼主2023/12/18 20:04
#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define ull unsigned long long
#define sort stable_sort 
#define endl '\n'
ll a[100001],m[100001],b[100001];
multiset<ll>s;
multiset<ll>::iterator it;
ll smul(ll a,ll b,ll p)
{
	ll ans=0;
	while(b)
	{
		if(b&1)
		{
			ans=(ans+a)%p;
		}
		b>>=1;
		a=(a+a)%p;
	}
	return (ans+p)%p;
}
ll gcd(ll a,ll b)
{
	return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b)
{
	return a/gcd(a,b)*b;
}
ll exgcd(ll a,ll b,ll &x,ll &y)
{
	if(b==0)
	{
		x=1;
		y=0;
		return a;
	}
	else
	{
		ll d=exgcd(b,a%b,y,x);
		y-=a/b*x;
		return d;
	}
}
ll excrt(ll n)
{
	ll mul=m[1],ans=a[1],x,y,c,d,i,maxx;
	it=s.upper_bound(a[1]);
	if(it!=s.begin())
	{
		it--;
	}
	maxx=(ll)ceil(1.0*a[1]/(*it));
	s.erase(it);
	s.insert(b[1]);
	for(i=2;i<=n;i++)
	{
		x=y=0;
		it=s.upper_bound(a[i]);
		if(it!=s.begin())
		{
			it--;
		}
		c=(a[i]-smul((*it),ans%m[i],m[i])+m[i])%m[i];
		maxx=max(maxx,(ll)ceil(1.0*a[i]/(*it)));
		d=exgcd((*it)*mul,m[i],x,y);
		if(c%d==0)
		{
			ans+=smul((x+m[i])%m[i],c/d,m[i])*(*it)*mul;
			mul=lcm(mul,m[i]);	
			ans=(ans%mul+mul)%mul;
		}
		else
		{
			return -1;
		}
		s.erase(it);
		s.insert(b[i]);
	}
	return ans+(ll)ceil(1.0*(maxx-ans)/mul)*mul;
}
int main()
{
	ll t,n,mm,i,j,pd;
	cin>>t;
	for(i=1;i<=t;i++)
	{
		cin>>n>>mm;
		s.clear();
		for(j=1;j<=n;j++)
		{	
			cin>>a[j];
		}
		for(j=1;j<=n;j++)
		{
			cin>>m[j];
		}
		for(j=1;j<=n;j++)
		{
			cin>>b[j];
		}	
		for(j=1;j<=mm;j++)
		{
			cin>>pd;
			s.insert(pd);
		}
		cout<<excrt(n)<<endl;
	}
	return 0;
}
2023/12/18 20:04
加载中...