博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[NOI2018]屠龙勇士
阅读量:4598 次
发布时间:2019-06-09

本文共 2298 字,大约阅读时间需要 7 分钟。

题目大意:

n条龙,每条龙有血量a和回血值p,当一条龙血量< 0时,他会不断回血直至≥0。若某一刻龙的血量为0,则该龙死亡。

你有m把剑,每把剑有攻击力atk,攻击一下造成的伤害等于atk。并且你杀死一条龙后会得到一把新的剑。

你必须要按顺序杀掉龙,并且每次选择的剑都是atk小于a且最大的那把(如果都不小于a则选atk最小的那一把),杀死后剑消失。

在打每条龙时,你必须用选择的这把剑攻击K次(对于所有n条龙,K相等),且你必须刚好把它打死。

问通过的最小K。若不存在,输出-1。

解题思路:

首先对于每条龙,攻击它的剑是确定的。我们用multiset维护一下,预处理出对于每条龙要用的剑。

其次,对于每一组数据,p要么为1,要么大于等于a。

我们对于p=1的情况,直接特判即可。

对于p大于等于a的情况,我们相当于得到了n个同余方程\(atk\times x\equiv a\pmod p\)。

首先把atk除过去(atk、a、p都先约去公因数,若约去后atk无逆元,则无解),

然后得到许多形如\(x\equiv a\pmod p\)的方程,我们要求最小公共解。

用扩展中国剩余定理即可,即用exgcd每次合并两个同余方程。

时间复杂度\(O(n\log n)\)。

C++ Code:

#include
#define islose(a)if(a)goto dieusing LoveLive=long long;const int N=100005;template
inline void read(T&d){ int c=getchar();d=0; for(;!isdigit(c);c=getchar()); for(;isdigit(c);c=getchar()) d=(d<<3)+(d<<1)+(c^'0');}template
T max(const T a,const T b){return a
swd;int n,m,g[N];LoveLive a[N],p[N],atk[N];LoveLive gcd(LoveLive a,LoveLive b){return b?gcd(b,a%b):a;}LoveLive exgcd(LoveLive a,LoveLive b,LoveLive&x,LoveLive&y){ if(b){ auto G=exgcd(b,a%b,y,x); y-=a/b*x; return G; } x=1,y=0; return a;}inline LoveLive mul(LoveLive a,LoveLive b,LoveLive p){ auto ans=a*b-(LoveLive)((long double)a/p*b+1e-9)*p; return(ans+p)%p;}LoveLive crt(){ LoveLive A=a[1],P=p[1],x,y,d; for(int i=2;i<=n;++i){ d=exgcd(P,p[i],x,y); if((A-a[i])%d)return -1; A-=P*mul((A-a[i])/d,x,(p[i]/d)); P=P/d*p[i]; A=(A+P)%P; } return(A+P)%P;}int main(){ int T; for(read(T);T--;){ swd.clear(); read(n),read(m); bool p_1=true; for(int i=1;i<=n;++i)read(a[i]); for(int i=1;i<=n;++i)read(p[i]),p_1=p_1&&p[i]==1; for(int i=1;i<=n;++i)read(g[i]); while(m--){ int p; read(p); swd.insert(p); } for(int i=1;i<=n;++i){ auto it=swd.upper_bound(a[i]); if(it!=swd.begin())--it; atk[i]=*it; swd.erase(it); swd.insert(g[i]); } LoveLive ans=0,aans; for(int i=1;i<=n;++i) ans=max(ans,(a[i]-1)/atk[i]+1); if(p_1){ printf("%lld\n",ans); continue; } for(int i=1;i<=n;++i){ auto G=gcd(p[i],atk[i]); islose(a[i]%G); p[i]/=G,atk[i]/=G,a[i]/=G; LoveLive x,y; exgcd(atk[i],p[i],x,y); x=(x%p[i]+p[i])%p[i]; a[i]=mul(a[i],x,p[i]); } aans=crt(); islose(aans==-1); if(aans

 

转载于:https://www.cnblogs.com/Mrsrz/p/9350077.html

你可能感兴趣的文章
Mvc多级Views目录 asp.net mvc4 路由重写及 修改view 的寻找视图的规则
查看>>
spring整合redis
查看>>
GitLab Runner and CICD
查看>>
【XSY2721】求和 杜教筛
查看>>
常见的SQL优化面试题
查看>>
angular在IE9中的坑
查看>>
[leetcode]35.Search Insert Position
查看>>
xshell鼠标文本设置
查看>>
java中连接各种数据的方法
查看>>
移动端网页头部标签模板
查看>>
每日一练3
查看>>
SaltStack系列(二)之常用模块
查看>>
Day4
查看>>
OpenMobile's Application Compatibility Layer (ACL)
查看>>
html中文件类型的accept属性有哪些
查看>>
JS及JQuery对Html内容编码,Html转义
查看>>
Coursera公开课笔记: 斯坦福大学机器学习第十课“应用机器学习的建议(Advice for applying machine learning)”...
查看>>
竞价广告系统-广告检索
查看>>
强哥PHP面向对象学习笔记
查看>>
[转]基于.NET平台常用的框架整理
查看>>