P4774 [NOI2018] 屠龙勇士 题解
题解
思路
由题目可知,一条龙被攻击 \(x\) 次并回复若干次后生命值恰好为 \(0\) 则死亡,可以得出如下式子:
\[\large ATK_i \cdot x \equiv a_i(\mod p_i)
\]
可推出,
\[\large x \equiv a_i \cdot ATK_i^{-1}(\mod p_i)
\]
需要求 \(ATK_i\) 在模 \(p_i\) 意义下的逆元。
我们自然会想到使用扩展欧几里得算法,但题中数据并不能保证 \(\gcd(ATK_i,p_i)\)。因此,需要将 \(ATK_i\)、\(a_i\) 和 \(p_i\) 同时除以 \(\gcd(ATK_i,p_i)\)。
此时,如果 \(\gcd(ATK_i,p_i) \nmid a_i\),那么此方程无解,方程组也无解。
于是我们得到了如下式子:
\[\large x \equiv \frac{a_i}{\gcd(ATK_i,p_i)} \cdot [\frac{ATK_i}{\gcd(ATK_i,p_i)}]^{-1}(\mod \frac{p_i}{\gcd(ATK_i,p_i)})
\]
看起来很吓人,但写起来一点也不吓人。
于是我们得到了一个标准的 exCRT 问题。直接套用求解即可。
注意,攻击次数 \(x\) 应当保证每一条龙打 \(x\) 下后生命值都不大于 \(0\)。不然回复不了。
实现
注意多测。
首先需要求出每条龙的 \(ATK\)。类似于求 \(a_i\) 在数组中的前驱。
可以用平衡树实现,但是 注意到标签里并没有平衡树 笔者平衡树写挂了 这样做太麻烦,于是我们使用multiset
。
在对每一个方程进行转化的过程中和 exCRT 中判断无解。
代码
\(\gcd\) 和 exgcd 就不放了,注意开__int128
。
对每一个方程进行转化:
bool calc() { for(int i=1;i<=n;i++) { long long gcd1=gcd(atk[i],p[i]); if(a[i]%gcd1) return 0; atk[i]/=gcd1,p[i]/=gcd1,a[i]/=gcd1; __int128 x,y; exgcd(atk[i],p[i],x,y); b[i]=a[i]*x%p[i]; } return 1; }
exCRT:
long long exCRT() { for(int i=2;i<=n;i++) { __int128 x,y; __int128 gcd1=exgcd(p[1],p[i],x,y); if((b[i]-b[1])%gcd1) return -1; x*=(b[i]-b[1])/gcd1; x%=p[i]/gcd1; b[1]+=p[1]*x; p[1]*=p[i]/gcd1; } b[1]=(b[1]%p[1]+p[1])%p[1]; return b[1]; }
主体部分:
注意多测
ms.clear(); //multiset scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); for(int i=1;i<=n;i++) scanf("%lld",&p[i]); for(int i=1;i<=n;i++) scanf("%lld",&rew[i]); while(m--) { long long tmp; scanf("%lld",&tmp); ms.insert(tmp); } for(int i=1;i<=n;i++) { auto pos=ms.upper_bound(a[i]); if(pos!=ms.begin()) pos--; atk[i]=*pos; ms.erase(pos); ms.insert(rew[i]); } long long mtimes=0; for(int i=1;i<=n;i++) mtimes=std::max(mtimes,(long long)((a[i]+atk[i]-1)/atk[i])); //std::max()比较不了__int128 if(!calc()) printf("-1\n"); else { long long ans=exCRT(); if(ans==-1) { printf("-1\n"); continue; } long long tmp1=mtimes/p[1]; ans+=p[1]*tmp1; if(ans<mti) ans+=p[1]; printf("%lld\n",ans); }
\[\huge End
\]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】