这个还是比较好推的~
#include <set> #include <cstdio> #include <string> #include <algorithm> #define N 200000 #define ll long long #define ull unsigned long long using namespace std; void setIO(string s) { string in=s+".in",out=s+".out"; freopen(in.c_str(),"r",stdin); // freopen(out.c_str(),"w",stdout); } int cas; multiset<ll>S; multiset<ll>::iterator it; ll A[N],P[N],Power[N],reward[N]; ll mult(ll x,ll y,ll mod) { ll tmp=(long double)x/mod*y; return ((ull)x*y-(ull)tmp*mod+mod)%mod; } ll qpow(ll base,ll k,ll mod) { ll tmp=1; for(;k;base=mult(base,base,mod),k>>=1) if(k&1) tmp=mult(tmp,base,mod); return tmp; } ll exgcd(ll a,ll b,ll &x,ll &y) { if(!b) { x=1,y=0; return a; } ll gcd=exgcd(b,a%b,x,y),tmp=x; x=y,y=tmp-a/b*y; return gcd; } void solve() { S.clear(); ll ans,M,Max=0; int i,j,n,m,flag=0,nosol=0; scanf("%d%d",&n,&m); for(i=1;i<=n;++i) scanf("%lld",&A[i]); for(i=1;i<=n;++i) scanf("%lld",&P[i]); for(i=1;i<=n;++i) scanf("%lld",&reward[i]); for(i=1;i<=m;++i) scanf("%lld",&Power[i]),S.insert(Power[i]); for(i=1;i<=n;++i) { ll cur; it=S.upper_bound(A[i]); if(it!=S.begin()) it--; cur=(*it); S.erase(it); S.insert(reward[i]); Max=max(Max,A[i]%cur==0?A[i]/cur:A[i]/cur+1); if(A[i]>P[i]) { flag=1; } ll a,b,x,y,c,gcd; a=cur,b=P[i],c=A[i]; gcd=exgcd(a,b,x,y),b=abs(b/gcd); if(c%gcd) { nosol=1; break; } x=(mult(x,c/gcd,b)+b)%b; // 当前这局的 if(i==1) ans=x,M=b; else { ll curans=x,curM=b; a=M,b=curM,c=curans-ans; gcd=exgcd(a,b,x,y); if(c%gcd) { nosol=1; break; } b=abs(b/gcd); x=(mult(x,c/gcd,b)+b)%b; ans+=M*x; M*=curM/__gcd(M,curM); ans=(ans%M+M)%M; } } if(nosol) printf("-1\n"); else printf("%lld\n",flag?Max:ans); } int main() { int i,j,T; // setIO("input"); scanf("%d",&T); for(cas=1;cas<=T;++cas) solve(); return 0; }
BZOJ 5418: [Noi2018]屠龙勇士 EXCRT+multiset
原文:https://www.cnblogs.com/guangheli/p/11516855.html