昨天晚上快走时看了这题:不是exgcd+excrt吗?
旁边张大佬默默看了我一眼(觉得我会死)
然后于是我今天中午才调出来Orz
思路:exgcd+excrt
提交:5次
错因:龟速乘传进去了负数,并且用的int;之前写过的excrt的板子有问题
题解:
先要特判一种情况:若 \(p[i]=1\) ,答案显然就是 \(\max(\lceil\frac{a[i]}{stk[i]}\rceil)\) ,只需要把龙打成负血他就死了。
先是这样的一些方程:设 \(atk[i]\) 表示对于第 \(i\) 只龙使用攻击力为 \(atk[i]\) 的剑
\[atk[i]*x_i \equiv a[i] \mod p[i] \]
好的这样我们可以 exgcd 解出 \(X_i=x_i*\frac{a[i]}{gcd(atk[i],p[i])}\)
我们知道,对于上面的方程来说,\(X_i+k*\frac{p[i]}{gcd(atk[i],p[i])},k\in Z\)
设 \(b[i]=\frac{p[i]}{gcd(atk[i],p[i])}\) ,所以对于最终答案\(ans\)有:
\[ans\equiv X_i \mod b[i]\]
这个 \(ans\) 是可以用 excrt 合并的。
代码:
#include<bits/stdc++.h> #define ll long long #define R register int using namespace std; namespace Luitaryi { template<class I> inline I g(I& x) { x=0; register I f=1; register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f; do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*=f; } template<class I> inline I ps(I x) { if(x<0) putchar('-'),x=-x; static char s[40]; register int sz=0; while(x!=0) s[++sz]=x%10,x/=10; while(sz) putchar(s[sz]+'0'),--sz; } const int N=100010; inline ll exgcd(ll& x,ll& y,ll a,ll b) { if(!b) {x=1,y=0; return a;} register ll d=exgcd(y,x,b,a%b); y-=a/b*x; return d; } int T,n,m; ll s[N],b[N],c[N],a[N],mx; multiset<ll> ss; bool flg; multiset<ll>::iterator it; inline ll mul(ll a,ll b,ll p) { register ll ret=0; for(;b;b>>=1,a=(a+a)%p) if(b&1) ret=(ret+a)%p; ret=(ret+p)%p; return ret; } inline void main() { g(T); while(T--) { mx=0,flg=true; register ll ans=0,sum=1,x,y; g(n),g(m); for(R i=1;i<=n;++i) g(s[i]); for(R i=1;i<=n;++i) g(b[i]),flg&=b[i]==1; for(R i=1;i<=n;++i) g(c[i]); for(R i=1;i<=m;++i) g(x),ss.insert(x); for(R i=1;i<=n;++i) { it=ss.upper_bound(s[i]); if(it!=ss.begin()) --it; a[i]=*it,ss.erase(it),ss.insert(c[i]); mx=max((s[i]+a[i]-1)/a[i],mx); } if(flg) { printf("%lld\n",mx); goto end; } for(R i=1;i<=n;++i) { register ll x,y; register ll d=exgcd(x,y,a[i],b[i]); if(s[i]%d) {puts("-1"); goto end;} b[i]/=d,x=(x%b[i]+b[i])%b[i]; s[i]=mul(x,((s[i]/d)%b[i]+b[i])%b[i],b[i]); } for(R i=1;i<=n;++i) { register ll d=exgcd(x,y,sum,b[i]); if((s[i]-ans)%d) {puts("-1"); goto end;} b[i]/=d; x=mul(x,((s[i]-ans)/d%b[i]+b[i])%b[i],b[i]); ans+=x*sum,sum=sum*b[i]; } printf("%lld\n",(ans%sum+sum)%sum); end:ss.clear(); } } } signed main() {Luitaryi::main(); return 0;}
2019.09.03
66