首先對於每一個龍用哪一個劍砍,咱們能夠用set隨便模擬一下獲得。git
而後求出拿這個劍砍這條龍的答案 $$ atk_ix-p_iy=a_i $$ 其中$atk_i$是砍第$i$條龍的劍的攻擊力,$p_i$是龍的回覆係數,$a_i$是初始生命值,而後$x$就是單獨考慮這個劍砍這個龍的答案。spa
咱們能夠拿exgcd去解這個方程,可是冷靜分析一波,咱們發現回覆次數$y$須要非負。code
而後咱們再冷靜一波,發現$p_i\not=1$的數據都有一個叫性質$1$的東西是$a_i\le p_i$get
在性質$1$的狀況下,由於$atk_i$和$x$都是非負的,因此$y<0$的時候顯然是無解的it
而後發現$p_i$都等於$1$的時候,咱們只須要取最大的生命值就能夠了io
而後快樂的解一下這個方程class
注意一件事,能夠獲得通解$x$是在$\pmod {\frac{p_i}{\gcd(p_i,atk_i)}}$下的gc
這樣咱們就獲得了不少個同餘方程,而後excrt合併就能夠了數據
Code:di
#include <cstdio> #include <cctype> #include <algorithm> #include <set> #define ll long long using std::max; const int SIZE=1<<21; char ibuf[SIZE],*iS,*iT; #define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),iS==iT?EOF:*iS++):*iS++) //#define gc() getchar() template <class T> void read(T &x) { x=0;char c=gc(); while(!isdigit(c)) c=gc(); while(isdigit(c)) x=x*10+c-'0',c=gc(); } std::multiset <ll> s; std::multiset <ll>::iterator it; const int N=1e5+10; int n,m; ll hp[N],p[N],atk[N],A[N],B[N]; ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} void exgcd(ll a,ll b,ll &x,ll &y) { if(!b) { x=1,y=0; return; } exgcd(b,a%b,x,y); ll tmp=x; x=y; y=tmp-a/b*y; } ll mul(ll d,ll k,ll p) { ll f=0; while(k) { if(k&1) (f+=d)%=p; (d+=d)%=p; k>>=1; } return f; } void work() { ll mx=0; s.clear(); read(n),read(m); for(int i=1;i<=n;i++) read(hp[i]); for(int i=1;i<=n;i++) read(p[i]); for(int i=1;i<=n;i++) read(atk[i]); for(int i=1;i<=m;i++) { ll x; read(x); s.insert(x); } for(int i=1;i<=n;i++) { ll a,b,c,x,y; it=s.upper_bound(hp[i]); if(it==s.begin()) { b=*it; s.erase(it); } else { it--; b=*it; s.erase(it); } a=b,b=p[i],c=hp[i]; ll d=gcd(a,b); if(c%d!=0) { puts("-1"); return; } mx=max(mx,(c-1)/a+1); exgcd(a,b,x,y); x=mul(x,c/d,b/d); x=(x%(b/d)+b/d)%(b/d); A[i]=x,B[i]=b/d; s.insert(atk[i]); } for(int i=2;i<=n;i++) { if(A[i]==A[i-1]) { B[i]=B[i]/gcd(B[i],B[i-1])*B[i-1]; continue; } if(A[i]<A[i-1]) std::swap(A[i],A[i-1]),std::swap(B[i],B[i-1]); ll a=B[i-1],b=B[i],c=A[i]-A[i-1],d=gcd(a,b),x,y; if(c%d!=0) { puts("-1"); return; } exgcd(a,b,x,y); x=mul(x,c/d,b/d); B[i]=a/d*b; A[i]=((A[i-1]+mul(x,B[i-1],B[i]))%B[i]+B[i])%B[i]; } printf("%lld\n",max(A[n],mx)); } int main() { freopen("dragon.in","r",stdin); freopen("dragon.out","w",stdout); int T;read(T); while(T--) work(); return 0; }
2019.4.30