[LOJ 2721][UOJ 396][BZOJ 5418][NOI 2018]屠龙勇士

题意

题面好啰嗦啊直接粘LOJ题面好了

小 D 最近在网上发现了一款小游戏。游戏的规则如下:

  • 游戏的目标是按照编号 \(1\)~\(n\) 顺序杀掉 \(n\) 条巨龙,每条巨龙拥有一个初始的生命值 \(a_i\) 。同时每条巨龙拥有恢复能力,当其使用恢复能力时,它的生命值就会每次增加 \(p_i\),直至生命值非负。只有在攻击结束后且当生命值恰好为 \(0\) 时它才会死去。
  • 游戏开始时玩家拥有 \(m\) 把攻击力已知的剑,每次面对巨龙时,玩家只能选择一把剑,当杀死巨龙后这把剑就会消失,但作为奖励,玩家会获得全新的一把剑。

小 D 觉得这款游戏十分无聊,但最快通关的玩家可以获得 ION2018 的参赛资格, 于是小 D 决定写一个笨笨的机器人帮她通关这款游戏,她写的机器人遵循以下规则:

  • 每次面对巨龙时,机器人会选择当前拥有的,攻击力不高于巨龙初始生命值中攻击力最大的一把剑作为武器。如果没有这样的剑,则选择攻击力最低的一把剑作为武器。
  • 机器人面对每条巨龙,它都会使用上一步中选择的剑攻击巨龙固定的 \(x\) 次,使巨龙的生命值减少 \(x \times ATK\)。
  • 之后,巨龙会不断使用恢复能力,每次恢复 \(p_i\) 生命值。若在使用恢复能力前或某一次恢复后其生命值为 \(0\),则巨龙死亡,玩家通过本关。

那么显然机器人的攻击次数是决定能否最快通关这款游戏的关键。小 D 现在得知了每条巨龙的所有属性,她想考考你,你知道应该将机器人的攻击次数 \(x\) 设置为多少,才能用最少的攻击次数通关游戏吗?

当然如果无论设置成多少都无法通关游戏,输出 \(-1\) 即可。

杀龙的时候需要三步必杀, 不能重复多次qwq...

\(n\le 10^5,m\le 10^5,a_i\le 10^{12}\).

对于所有的测试点,\(T \le 5\),所有武器的攻击力 \(\le 10^6\),所有 \(p_i\) 的最小公倍数 \(\le 10^{12}\)。

题解

乍一看这题神仙的一匹, 然而冷静分析一下可以发现:

拿来淦龙的剑都是固定的, 而且每次相当于把龙的血打到一个不大于 \(0\) 的 \(p_i\) 的倍数就可以完成任务了.

那么也就是说只要让 \(x\) 满足:

\[x\times ATK_i\equiv a_i \pmod {p_i}\\
x\times ATK_i\ge a_i
\]

先来搞第一个限制.

不难发现这个限制相当于下式:

\[x\times ATK_i+k\times p_i=a_i
\]

其中 \(ATK_i,p_i,a_i\) 都是确定的, 显然这个东西可以随手 ExGCD 搞一搞解出一个 \(\bmod p_i\) 意义下的 \(x\).

不过注意这一步要对 \(ATK_i\) 和 \(p_i\) 进行约分, 不然逆元不唯一就会解出奇怪的东西qaq(sb rvalue在这坑了一个小时)...

然后我们不难发现我们得到了一堆形如这样的方程组:

\[x\equiv r_i \pmod {p_i}
\]

这不裸的 CRT 么?

然而 \(p_i\) 不互质. 并不能直接 CRT.

考虑 ExCRT. ExCRT 的大体思路是通过 ExGCD 来合并两个同余方程.

假设我们现在有两个同余方程:

\[\begin{cases}
x\equiv a &\pmod n\\
x\equiv b &\pmod m
\end{cases}
\]

不难发现它等价于:

\[\begin{cases}
x = a + pn\\
x = b + qm
\end{cases}
\]

那么也就是说:

\[a+pn=b+qm
\]

移项可得:

\[a-b=qm-pn
\]

好了我们可以 ExGCD 了.

算出 \(p\) 和 \(q\) 之后可以用 \(x=a+pn=b+pm\) 算出 \(x\) 来. 它与所有 \(\bmod \gcd(n,m)\) 意义下同余的值都是这两个方程的解. 显然我们直接对 \(\gcd(n,m)\) 取模就可以得到最小值了.

一直这样合并下去, 只要 ExGCD 的时候出锅那么根据Bézout定理这个方程组无解.

然后我们可以得到一个 \(\bmod \operatorname{lcm} \{p_i\}\) 的 \(x\). 接着考虑第二种限制.

显然我们可以对当前已有的 \(x\) 计算它是否满足 \(x\times ATK_i\ge a_i\), 如果不满足的话把 \(x\) 变为 \(\bmod \operatorname{lcm} \{p_i\}\) 意义下同余的最小满足条件的值就可以了. 不难发现答案就是:

\[x+\operatorname{lcm}\{p_i\}\times \max_{1\le i\le n}\left \lceil \frac {\left \lceil \frac{a_i}{ATK_i}\right \rceil-x}{\operatorname{lcm}\{p_i\}}\right \rceil
\]

UOJ因为有Hack所以数据比LOJ强一些, LOJ过了之后建议在UOJ上交一发.

参考代码

下面这份代码在发文时没有被Hack qwq...

#include <bits/stdc++.h>

const int MAXN=1e5+10;
typedef long long intEx; struct Equation{
intEx mod;
intEx rest;
};
Equation E[MAXN]; int n;
int m;
intEx a[MAXN];
intEx p[MAXN];
intEx w[MAXN];
intEx atk[MAXN]; intEx Mul(intEx,intEx,intEx);
intEx ExGCD(intEx,intEx,intEx&,intEx&); int main(){
int T;
scanf("%d",&T);
while(T--){
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",w+i);
std::multiset<intEx> s;
for(int i=1;i<=m;i++){
intEx x;
scanf("%lld",&x);
s.insert(x);
}
try{
for(int i=1;i<=n;i++){
E[i].mod=p[i];
auto it=s.upper_bound(a[i]);
if(it!=s.begin())
--it;
intEx t;
atk[i]=*it;
s.erase(it);
intEx gcd=ExGCD(atk[i],p[i],E[i].rest,t);
if(a[i]%gcd!=0)
throw std::logic_error(R"(a[i]%gcd!=0)");
E[i].mod/=gcd;
E[i].rest=Mul(a[i]/gcd,E[i].rest,E[i].mod);
(E[i].rest+=E[i].mod)%=E[i].mod;
s.insert(w[i]);
}
for(int i=2;i<=n;i++){
intEx x,y;
intEx gcd=ExGCD(E[i-1].mod,E[i].mod,x,y);
intEx lcm=E[i-1].mod/gcd*E[i].mod;
if((E[i-1].rest-E[i].rest)%gcd!=0)
throw std::logic_error(R"((E[i].rest-E[i-1].rest)%gcd!=0 @)"+std::to_string(i));
intEx scale=(E[i-1].rest-E[i].rest)/gcd;
(E[i].rest+=Mul(Mul(scale,y,lcm),E[i].mod,lcm))%=lcm;
E[i].mod=lcm;
E[i].rest=(E[i].rest+lcm)%lcm;
}
intEx scale=0;
for(int i=1;i<=n;i++)
scale=std::max(scale,((a[i]+atk[i]-1)/atk[i]-E[n].rest+E[n].mod-1)/E[n].mod);
printf("%lld\n",E[n].rest+scale*E[n].mod);
}
catch(std::logic_error x){
puts("-1");
continue;
}
}
return 0;
} intEx ExGCD(intEx a,intEx b,intEx& x,intEx& y){
if(b==0){
x=1;
y=0;
return a;
}
intEx gcd=ExGCD(b,a%b,y,x);
y-=(a/b)*x;
return gcd;
} intEx Mul(intEx a,intEx b,intEx p){
return __int128(a)*b%p;
}

[LOJ 2721][UOJ 396][BZOJ 5418][NOI 2018]屠龙勇士的更多相关文章

  1. [LOJ 2718][UOJ 393][BZOJ 5415][NOI 2018]归程

    [LOJ 2718][UOJ 393][BZOJ 5415][NOI 2018]归程 题意 给定一张无向图, 每条边有一个距离和一个高度. 再给定 \(q\) 组可能在线的询问, 每组询问给定一个点 ...

  2. [LOJ 2134][UOJ 132][BZOJ 4200][NOI 2015]小园丁与老司机

    [LOJ 2134][UOJ 132][BZOJ 4200][NOI 2015]小园丁与老司机 题意 给定平面上的 \(n\) 个整点 \((x_i,y_i)\), 一共有两个问题. 第一个问题是从原 ...

  3. [LOJ 2133][UOJ 131][BZOJ 4199][NOI 2015]品酒大会

    [LOJ 2133][UOJ 131][BZOJ 4199][NOI 2015]品酒大会 题意 给定一个长度为 \(n\) 的字符串 \(s\), 对于所有 \(r\in[1,n]\) 求出 \(s\ ...

  4. [LOJ 2083][UOJ 219][BZOJ 4650][NOI 2016]优秀的拆分

    [LOJ 2083][UOJ 219][BZOJ 4650][NOI 2016]优秀的拆分 题意 给定一个字符串 \(S\), 求有多少种将 \(S\) 的子串拆分为形如 AABB 的拆分方案 \(| ...

  5. NOI 2018 屠龙勇士 (拓展中国剩余定理excrt+拓展欧几里得exgcd)

    题目大意:略 真是一波三折的一道国赛题,先学了中国剩余定理,勉强看懂了模板然后写的这道题 把取出的宝剑攻击力设为T,可得Ti*x=ai(mod pi),这显然是ax=c(mod b)的形式 这部分用e ...

  6. [LOJ 2720][BZOJ 5417][UOJ 395][NOI 2018]你的名字

    [LOJ 2720][BZOJ 5417][UOJ 395][NOI 2018]你的名字 题意 给定一个大串 \(S\) 以及 \(q\) 次询问, 每次询问给定一个串 \(T\) 和区间 \([l, ...

  7. UOJ #449. 【集训队作业2018】喂鸽子

    UOJ #449. [集训队作业2018]喂鸽子 小Z是养鸽子的人.一天,小Z给鸽子们喂玉米吃.一共有n只鸽子,小Z每秒会等概率选择一只鸽子并给他一粒玉米.一只鸽子饱了当且仅当它吃了的玉米粒数量\(≥ ...

  8. LOJ #2721. 「NOI2018」屠龙勇士(set + exgcd)

    题意 LOJ #2721. 「NOI2018」屠龙勇士 题解 首先假设每条龙都可以打死,每次拿到的剑攻击力为 \(ATK\) . 这个需要支持每次插入一个数,查找比一个 \(\le\) 数最大的数(或 ...

  9. loj#2721. 「NOI2018」屠龙勇士

    题目链接 loj#2721. 「NOI2018」屠龙勇士 题解 首先可以列出线性方程组 方程组转化为在模p意义下的同余方程 因为不保证pp 互素,考虑扩展中国剩余定理合并 方程组是带系数的,我们要做的 ...

随机推荐

  1. vue表格合并行的一个实例

        一.element控件实现 在平常的应用中,需要用到合并单元格的操作,在Excel中,这种操作很好实现,但在实际项目中,常常需要借助element控件来实现. 下面是element中的一个实例 ...

  2. Ubuntu Idea 快捷键 Ctrl+Alt+S 无法使用解决

    Idea 里习惯了用 Ctrl+Alt+S 打开设置界面,在 Ubuntu 下会因为快捷键冲突无法使用 系统快捷键 打开系统设置中的快捷键设置,按 Backspace 键禁用 Fcitx 如果你的输入 ...

  3. 抓包工具之fiddler实战2-设置断点

    Fiddler作为抓工具包,功能强大,作为代理服务器,可以对抓获到的请求或响应进行修改,然后模拟客户端发送新的请求或模拟服务器返回修改后的响应结果. Fiddler中设置断点修改Request Fid ...

  4. Sublime和VSCode生成基础HTML代码

    我们在编写前端页面时,常希望能自动生成基础的HTML代码.而在Sublime和VSCode就有这样的功能 在Sublime中,在编辑栏输入html,然后敲Tab键,则自动生成代码如下: <!DO ...

  5. 导出HTML5 Canvas图片并上传服务器功能

    这篇文章主要介绍了导出HTML5 Canvas图片并上传服务器功能,文中通过实例代码给大家介绍了HTML5 Canvas转化成图片后上传服务器,代码简单易懂非常不错,具有一定的参考借鉴价值,需要的朋友 ...

  6. node-sass安装失败处理办法

    参考: https://npm.taobao.org/mirrors https://lzw.me/a/node-sass-install-helper.html 设置环境变量安装 SASS_BINA ...

  7. Go template高级用法、深入详解、手册、指南、剖析

    入门示例 以下为test.html文件的内容,里面使用了一个template语法{{.}}. <!DOCTYPE html> <html> <head> <m ...

  8. java基础(25):Properties、序列化流、打印流、commons-IO

    1. Properties类 1.1 Properties类介绍 Properties 类表示了一个持久的属性集.Properties 可保存在流中或从流中加载.属性列表中每个键及其对应值都是一个字符 ...

  9. linux下 sort | uniq | wc | less 几个命令的基本用法

    sort -f :忽略大小写的差异,例如 A 与 a 视为编码相同: -b :忽略最前面的空格符部分: -M :以月份的名字来排序,例如 JAN, DEC 等等的排序方法: -n :使用『纯数字』进行 ...

  10. VUE组内培训

    最近去参加了一个外部VUE的周末培训,加上自己比较感兴趣所以对这项很热的前端框架做了点学习,顺便给组内同事做个简单的分享,希望下次有项目可以使用上- VUE的语法教程网上很多我就不一一列举,截图放一下 ...