[NOI2018]屠龙勇士

描述

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

游戏的目标是按照编号 1∼n 顺序杀掉 n 条巨龙,每条巨龙拥有一个初始的生命值 ai 。同时每条巨龙拥有恢复能力,当其使用恢复能力时,它的生命值就会每次增加 pi,直至生命值非负。只有在攻击结束后且当生命值恰好为 0 时它才会死去。

游戏开始时玩家拥有 m 把攻击力已知的剑,每次面对巨龙时,玩家只能选择一把剑,当杀死巨龙后这把剑就会消失,但作为奖励,玩家会获得全新的一把剑。

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

每次面对巨龙时,机器人会选择当前拥有的,攻击力不高于巨龙初始生命值中攻击力最大的一把剑作为武器。如果没有这样的剑,则选择攻击力最低的一把剑作为武器。

机器人面对每条巨龙,它都会使用上一步中选择的剑攻击巨龙固定的 x 次,使巨龙的生命值减少 x×ATK。

之后,巨龙会不断使用恢复能力,每次恢复 pi 生命值。若在使用恢复能力前或某一次恢复后其生命值为 0,则巨龙死亡,玩家通过本关。

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

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

输入格式

从标准输入读入数据。

第一行一个整数 T,代表数据组数。

接下来 T 组数据,每组数据包含 5 行。

每组数据的第一行包含两个整数,n 和 m,代表巨龙的数量和初始剑的数量;

接下来一行包含 n 个正整数,第 i 个数表示第 i 条巨龙的初始生命值 ai;

接下来一行包含 n 个正整数,第 i 个数表示第 i 条巨龙的恢复能力 pi;

接下来一行包含 n 个正整数,第 i 个数表示杀死第 i 条巨龙后奖励的剑的攻击力;

接下来一行包含 m 个正整数,表示初始拥有的 m 把剑的攻击力。

输出格式

输出到标准输出中。

一共 T 行。

第 i 行一个整数,表示对于第 i 组数据,能够使得机器人通关游戏的最小攻击次数 x,如果答案不存在,输出 −1。

样例一

input

2

3 3

3 5 7

4 6 10

7 3 9

1 9 1000

3 2

3 5 6

4 8 7

1 1 1

1 1

output

59

-1

explanation

第一组数据:

开始时拥有的剑的攻击力为 {1,9,1000},第 1 条龙生命值为 3,故选择攻击力为 1 的剑,攻击 59 次,造成 59 点伤害,此时龙的生命值为 −56,恢复 14 次后生命值恰好为 0,死亡。

攻击力为 1 的剑消失,拾取一把攻击力为 7 的剑,此时拥有的剑的攻击力为 {7,9,1000},第 2 条龙生命值为 5,故选择攻击力为 7 的剑,攻击 59 次,造成 413 点伤害,此时龙的生命值为 −408,恢复 68 次后生命值恰好为 0,死亡。

此时拥有的剑的攻击力为 {3,9,1000},第 3 条龙生命值为 7,故选择攻击力为 3 的剑,攻击 59 次,造成 177 点伤害,此时龙的生命值为 −170,恢复 17 次后生命值恰好为 0,死亡。

没有比 59 次更少的通关方法,故答案为 59。

第二组数据:

不存在既能杀死第一条龙又能杀死第二条龙的方法,故无法通关,输出 −1。





excrt 板子题,就是看你细不细心,注意要乘爆longlong, 所以要做快速乘QAQ。。。


#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
struct lpl{
long long atk, ai, pi, data;
}dra[maxn];
int n, m, tag;
long long mn;
long long sw[maxn];
multiset<long long> s;
multiset<long long>::iterator iter; inline long long fc(long long A, long long B, long long P){
bool tag = false; if(B < 0){B = -B; tag = true;}
long long ret = 0, tmp = A;
while(B){
if(B & 1) ret = (ret + tmp) % P;
tmp = (tmp + tmp) % P; B >>= 1;
}
return (tag) ? -ret : ret;
} long long Gcd(long long a, long long b){return (a % b == 0) ? (b) : (Gcd(b, a % b));} long long exgcd(long long a, long long b, long long &x, long long &y){
if(a == 1 && b == 0){x = 1; y = 0; return a;}
long long g = exgcd(b, a % b, x, y);
long long tmpx = x, tmpy = y;
x = tmpy; y = tmpx - a / b * tmpy; return g;
} inline void putit(){
scanf("%d%d", &n, &m); long long lin; s.clear(); tag = 0; mn = 0; s.insert(0);
for(int i = 1; i <= n; ++i) scanf("%lld", &dra[i].ai);
for(int i = 1; i <= n; ++i) scanf("%lld", &dra[i].pi);
for(int i = 1; i <= n; ++i) scanf("%lld", &sw[i]);
for(int i = 1; i <= m; ++i){scanf("%lld", &lin); s.insert(-lin);}
} inline void prepare(){
long long lin;
for(int i = 1; i <= n; ++i){
iter = s.lower_bound(-dra[i].ai); lin = *iter; if(!lin) iter--; lin = *iter;
dra[i].atk = (-1) * (lin); s.erase(iter); s.insert(-sw[i]);
mn = max(mn, ((dra[i].ai + dra[i].atk - 1) / dra[i].atk) );
}
} inline void workk(){
long long g, inv, lin;
for(int i = 1; i <= n; ++i){
g = Gcd(dra[i].atk, dra[i].pi);
if(dra[i].ai % g != 0){tag = 1; return;}
dra[i].atk /= g; dra[i].pi /= g; dra[i].ai /= g;
exgcd(dra[i].atk, dra[i].pi, inv, lin);
inv = (inv % dra[i].pi + dra[i].pi) % dra[i].pi;
dra[i].data = fc(inv, dra[i].ai, dra[i].pi);
}
} inline void excrt(){
lpl ret, lin = dra[1]; long long a, b, x, y, g;
for(int i = 2; i <= n; ++i){
lpl qwe = dra[i]; if(lin.data > qwe.data) swap(lin, qwe);
g = Gcd(lin.pi, qwe.pi); if((qwe.data - lin.data) % g != 0){tag = 1; return;}
lin.pi /= g; qwe.pi /= g;
exgcd(lin.pi, qwe.pi, x, y); ret.pi = lin.pi * qwe.pi * g;
x = fc(x, ((qwe.data - lin.data) / g), ret.pi); ret.data = fc(lin.pi * g, x, ret.pi); ret.data = (ret.data + lin.data) % ret.pi;
lin = ret;
}
if(lin.data >= mn){printf("%lld\n", lin.data); return;}
long long k = (mn - lin.data) / lin.pi; lin.data += k * lin.pi;
while(lin.data < mn) lin.data += lin.pi;
printf("%lld\n", lin.data);
} int main()
{
int T; scanf("%d", &T);
while(T--){
putit();
prepare();
workk();
if(tag){printf("-1\n"); continue;}
excrt();
if(tag){printf("-1\n"); continue;}
}
return 0;
}

uoj396 [NOI2018]屠龙勇士的更多相关文章

  1. BZOJ5418[Noi2018]屠龙勇士——exgcd+扩展CRT+set

    题目链接: [Noi2018]屠龙勇士 题目大意:有$n$条龙和初始$m$个武器,每个武器有一个攻击力$t_{i}$,每条龙有一个初始血量$a_{i}$和一个回复值$p_{i}$(即只要血量为负数就一 ...

  2. P4774 [NOI2018]屠龙勇士

    P4774 [NOI2018]屠龙勇士 先平衡树跑出打每条龙的atk t[] 然后每条龙有\(xt \equiv a[i](\text{mod }p[i])\) 就是\(xt+kp[i]=a[i]\) ...

  3. [洛谷P4774] [NOI2018]屠龙勇士

    洛谷题目链接:[NOI2018]屠龙勇士 因为markdown复制过来有点炸格式,所以看题目请戳上面. 题解: 因为杀死一条龙的条件是在攻击\(x\)次,龙恢复\(y\)次血量\((y\in N^{* ...

  4. BZOJ_5418_[Noi2018]屠龙勇士_exgcd+excrt

    BZOJ_5418_[Noi2018]屠龙勇士_exgcd+excrt Description www.lydsy.com/JudgeOnline/upload/noi2018day2.pdf 每次用 ...

  5. 洛谷 P4774 [NOI2018] 屠龙勇士

    链接:P4774 前言: 交了18遍最后发现是多组数据没清空/ll 题意: 其实就是个扩中. 分析过程: 首先发现根据题目描述的选择剑的方式,每条龙对应的剑都是固定的,有查询前驱,后继(在该数不存在前 ...

  6. 洛谷P4774 [NOI2018]屠龙勇士 [扩欧,中国剩余定理]

    传送门 思路 首先可以发现打每条龙的攻击值显然是可以提前算出来的,拿multiset模拟一下即可. 一般情况 可以搞出这么一些式子: \[ atk_i\times x=a_i(\text{mod}\ ...

  7. [NOI2018]屠龙勇士

    题目描述 题解 考虑增量法. 假设我们已经做完了前k个条件,前面的模数连乘起来的结果为M,答案为X,当前的攻击力为x,龙的血量为a. 那么我们这一次的答案的表达形式是X+t*M的. 这一次需要满足的是 ...

  8. LOJ2721 [NOI2018] 屠龙勇士 【扩展中国剩余定理】

    好久没写了,写一篇凑个数. 题目分析: 这题不难想,讲一下中国剩余定理怎么扩展. 考虑$$\left\{\begin{matrix}x \equiv a\pmod{b}\\ x \equiv c\pm ...

  9. Luogu P4774 / LOJ2721 【[NOI2018]屠龙勇士】

    真是个简单坑题...++ 前置: exgcd,exCRT,STL-multiset 读完题不难发现,攻击每条龙用的剑都是可以确定的,可以用multiset求.攻击最少显然应该对于每一条龙都操作一次,即 ...

随机推荐

  1. tar shell zip

    tar          打包后生成的文件名全路径                    要打包的目录 tar -czPf xx/script.tar.gz                      ...

  2. [AHOI2008]紧急集合 / 聚会(LCA)

    [AHOI2008]紧急集合 / 聚会 题目描述 欢乐岛上有个非常好玩的游戏,叫做"紧急集合".在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通 ...

  3. fork和vfork的区别

    参见百度百科API说明: fork 头文件: #include<unistd.h> #include<sys/types.h> 函数原型: pid_t fork( void); ...

  4. alert(1) to win 3

    function escape(s) { s = JSON.stringify(s); return '<script>console.log(' + s + ');</script ...

  5. ATM机取款过程

    假设一个简单的ATM机的取款过程是这样的:首先提示用户输入密码,最多只能输入三次,超过3次则提示用户“密码错误,请取卡”结束交易.如果用户密码正确,再提示用户输入取款金额,ATM机只能输出100元的纸 ...

  6. Task3.PyTorch实现Logistic regression

    1.PyTorch基础实现代码 import torch from torch.autograd import Variable torch.manual_seed(2) x_data = Varia ...

  7. Dubbo学习-7-dubbo配置文件优先级

    Dubbo配置加载流程 根据驱动方式的不同(比如Spring或裸API编程)配置形式上肯定会有所差异,具体参考XML配置.Annotation配置.API配置三篇文档.除了外围驱动方式上的差异,Dub ...

  8. PL/SQL 循环

    ----PL/SQL基本循环语句 LOOP DECLARE x ; BEGIN LOOP dbms_output.put_line(x); x :; THEN exit; END IF; END LO ...

  9. CF286E Ladies' Shop FFT

    题目链接 读完题后,我们发现如下性质: 在合法且和不超过 $m$ 的情况下,如果 $a_{i}$ 出现,则 $a_{i}$ 的倍数也必出现. 所以如果合法,只要对所有数两两结合一次就能得到所有 $a_ ...

  10. Jsoup学习和使用

    我们先看一下百度百科简介 它是java的HTML解析器 用HttpClient获取到网页后 具体的网页提取需要的信息的时候 ,就用到Jsoup,Jsoup可以使用强大的类似选择器,来获取需要的数据. ...