题目描述
小 D 最近在网上发现了一款小游戏。游戏的规则如下:
-
游戏的目标是按照编号 1→n1 \rightarrow n1→n 顺序杀掉 nnn 条巨龙,每条巨龙拥有一个初始的生命值 aia_iai 。同时每条巨龙拥有恢复能力,当其使用恢复能力时,它的生命值就会每次增加 pip_ipi ,直至生命值非负。只有在攻击结束后且当生命值 恰好 为 000 时它才会死去。
-
游戏开始时玩家拥有 mmm 把攻击力已知的剑,每次面对巨龙时,玩家只能选择一 把剑,当杀死巨龙后这把剑就会消失,但作为奖励,玩家会获得全新的一把剑。 小 D 觉得这款游戏十分无聊,但最快通关的玩家可以获得 ION2018 的参赛资格, 于是小 D 决定写一个笨笨的机器人帮她通关这款游戏,她写的机器人遵循以下规则:
-
每次面对巨龙时,机器人会选择当前拥有的,攻击力不高于巨龙初始生命值中攻击力最大的一把剑作为武器。如果没有这样的剑,则选择 攻击力最低 的一把剑作为武器。
-
机器人面对每条巨龙,它都会使用上一步中选择的剑攻击巨龙固定的 xxx 次,使巨龙的生命值减少 x×ATKx \times ATKx×ATK 。
-
之后,巨龙会不断使用恢复能力,每次恢复 pip_ipi 生命值。若在使用恢复能力前或某一次恢复后其生命值为 000 ,则巨龙死亡,玩家通过本关。
那么显然机器人的攻击次数是决定能否最快通关这款游戏的关键。小 D 现在得知了每条巨龙的所有属性,她想考考你,你知道应该将机器人的攻击次数 xxx 设置为多少,才能用最少的攻击次数通关游戏吗?
当然如果无论设置成多少都无法通关游戏,输出 −1-1−1 即可。
输入格式
第一行一个整数 TTT,代表数据组数。
接下来 TTT 组数据,每组数据包含 555 行。
-
每组数据的第一行包含两个整数,nnn 和 mmm ,代表巨龙的数量和初始剑的数量;
-
接下来一行包含 nnn 个正整数,第 iii 个数表示第 iii 条巨龙的初始生命值 aia_iai ;
-
接下来一行包含 nnn 个正整数,第 iii 个数表示第 iii 条巨龙的恢复能力 pip_ipi ;
-
接下来一行包含 nnn 个正整数,第 iii 个数表示杀死第 iii 条巨龙后奖励的剑的攻击力;
-
接下来一行包含 mmm 个正整数,表示初始拥有的 mmm 把剑的攻击力。
输出格式
一共 TTT 行。
第 iii 行一个整数,表示对于第 iii 组数据,能够使得机器人通关游戏的最小攻击次数 xxx ,如果答案不存在,输出 −1-1−1。
输入输出样例
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
59 -1
说明/提示
第一组数据:
-
开始时拥有的剑的攻击力为 {1,9,10}\{1,9,10\}{1,9,10},第 111 条龙生命值为 333,故选择攻击力为 111 的剑,攻击 595959 次,造成 595959 点伤害,此时龙的生命值为 −56-56−56,恢复 14 次后生命值恰好为 000,死亡。
-
攻击力为 111 的剑消失,拾取一把攻击力为 777 的剑,此时拥有的剑的攻击力为 {7,9,10}\{7,9,10\}{7,9,10},第 2 条龙生命值为 555,故选择攻击力为 777 的剑,攻击 595959 次,造成 413413413 点伤害,此时龙的生命值为 −408-408−408,恢复 686868 次后生命值恰好为 000,死亡。
-
此时拥有的剑的攻击力为 {3,9,10}\{3,9,10\}{3,9,10},第 333 条龙生命值为 777,故选择攻击力为 333 的剑,攻击 595959 次,造成 177177177 点伤害,此时龙的生命值为 −170-170−170,恢复 171717 次后生命值恰好为 0,死亡。
-
没有比 595959 次更少的通关方法,故答案为 595959。
第二组数据: 不存在既能杀死第一条龙又能杀死第二条龙的方法,故无法通关,输出 −1-1−1。
【子任务】
测试点编号 | nnn | mmm | pip_ipi | aia_iai | 攻击力 | 其他限制 |
---|---|---|---|---|---|---|
1 | ≤105\le 10^5≤105 | =1=1=1 | =1=1=1 | ≤105\le 10^5≤105 | =1=1=1 | 无 |
2 | ≤105\le 10^5≤105 | =1=1=1 | =1=1=1 | ≤105\le 10^5≤105 | =1=1=1 | 无 |
3 | ≤105\le 10^5≤105 | =1=1=1 | =1=1=1 | ≤105\le 10^5≤105 | ≤105\le 10^5≤105 | 无 |
4 | ≤105\le 10^5≤105 | =1=1=1 | =1=1=1 | ≤105\le 10^5≤105 | ≤105\le 10^5≤105 | 无 |
5 | ≤103\le 10^3≤103 | ≤103\le 10^3≤103 | ≤105\le 10^5≤105 | ≤105\le 10^5≤105 | ≤105\le 10^5≤105 | 特性 1、特性 2 |
6 | ≤103\le 10^3≤103 | ≤103\le 10^3≤103 | ≤105\le 10^5≤105 | ≤105\le 10^5≤105 | ≤105\le 10^5≤105 | 特性 1、特性 2 |
7 | ≤103\le 10^3≤103 | ≤103\le 10^3≤103 | ≤105\le 10^5≤105 | ≤105\le 10^5≤105 | ≤105\le 10^5≤105 | 特性 1、特性 2 |
8 | =1=1=1 | =1=1=1 | ≤108\le 10^8≤108 | ≤108\le 10^8≤108 | ≤106\le 10^6≤106 | 特性 1 |
9 | =1=1=1 | =1=1=1 | ≤108\le 10^8≤108 | ≤108\le 10^8≤108 | ≤106\le 10^6≤106 | 特性 1 |
10 | =1=1=1 | =1=1=1 | ≤108\le 10^8≤108 | ≤108\le 10^8≤108 | ≤106\le 10^6≤106 | 特性 1 |
11 | =1=1=1 | =1=1=1 | ≤108\le 10^8≤108 | ≤108\le 10^8≤108 | ≤106\le 10^6≤106 | 特性 1 |
12 | =1=1=1 | =1=1=1 | ≤108\le 10^8≤108 | ≤108\le 10^8≤108 | ≤106\le 10^6≤106 | 特性 1 |
13 | =1=1=1 | =1=1=1 | ≤108\le 10^8≤108 | ≤108\le 10^8≤108 | ≤106\le 10^6≤106 | 特性 1 |
14 | =105=10^5=105 | =105=10^5=105 | =1=1=1 | ≤108\le 10^8≤108 | ≤106\le 10^6≤106 | 无特殊限制 |
15 | =105=10^5=105 | =105=10^5=105 | =1=1=1 | ≤108\le 10^8≤108 | ≤106\le 10^6≤106 | 无特殊限制 |
16 | ≤105\le 10^5≤105 | ≤105\le 10^5≤105 | 所有 pip_ipi 是质数 | ≤1012\le 10^{12}≤1012 | ≤106\le 10^6≤106 | 特性 1 |
17 | ≤105\le 10^5≤105 | ≤105\le 10^5≤105 | 所有 pip_ipi 是质数 | ≤1012\le 10^{12}≤1012 | ≤106\le 10^6≤106 | 特性 1 |
18 | ≤105\le 10^5≤105 | ≤105\le 10^5≤105 | 无特殊限制 | ≤1012\le 10^{12}≤1012 | ≤106\le 10^6≤106 | 特性 1 |
19 | ≤105\le 10^5≤105 | ≤105\le 10^5≤105 | 无特殊限制 | ≤1012\le 10^{12}≤1012 | ≤106\le 10^6≤106 | 特性 1 |
20 | ≤105\le 10^5≤105 | ≤105\le 10^5≤105 | 无特殊限制 | ≤1012\le 10^{12}≤1012 | ≤106\le 10^6≤106 | 特性 1 |
特性 1 是指:对于任意的 iii,ai≤pia_i \le p_iai≤pi。
特性 2 是指:lcm(pi)≤106\operatorname{lcm}(p_i) \le 10^6lcm(pi)≤106,即所有 pip_ipi 的 最小公倍数 不大于 10610^6106。
对于所有的测试点,T≤5T \le 5T≤5,所有武器的攻击力 ≤106\le 10^6≤106,所有 pip_ipi 的最小公倍数 ≤1012\le 10^{12}≤1012。
保证 T,n,m T, n, m T,n,m 均为正整数。
【提示】
你所用到的中间结果可能很大,注意保存中间结果的变量类型。
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<set> #pragma GCC optimize(2) using namespace std; typedef long long LL; const int maxn = 1e5 + 10 ; LL a[maxn],p[maxn],atk[maxn],x,y,d; multiset<LL> sw; inline LL read() { LL w=1,s=0; char ch=getchar(); while(ch<'0' || ch>'9'){if(ch=='-')w=-1; ch=getchar();} while(ch>='0' && ch<='9'){s=s*10+ch-'0'; ch=getchar();} return w*s; } void ext_gcd(LL a,LL b,LL &d,LL &x,LL &y) { if (b==0) { d=a;x=1;y=0; return; } ext_gcd(b,a%b,d,y,x); y-=a/b*x; } inline LL ksc(LL x,LL y,LL p){ LL z=(long double)x/p*y; LL res=(unsigned long long)x*y-(unsigned long long)z*p; return (res+p)%p; } int main() { LL T,n,m,k,mx,c; T=read(); begin:while(T--){ n=read();m=read(); sw.clear(); register multiset<LL>::iterator it; for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i<=n;i++) p[i]=read(); for(int i=1;i<=n;i++) atk[i]=read(); for(int i=1;i<=m;i++) sw.insert(read()); mx=c=0;m=1; for(int i=1;i<=n;i++){ it=sw.upper_bound(a[i]); if(sw.begin()!=it) it--; k=*it;sw.erase(it);sw.insert(atk[i]); mx=max(mx,(a[i]-1)/k+1);//更新限制 k%=p[i];a[i]%=p[i]; if(!k && !p[i]) continue; ext_gcd(k,p[i],d,x,y); p[i]/=d; a[i]=ksc(a[i]/d,(x%p[i]+p[i])%p[i],p[i]); ext_gcd(m,p[i],d,x,y); if((a[i]-c)%d){ puts("-1");goto begin; } m=m/d*p[i]; c=(c+ksc( ksc(m/p[i],((a[i]-c)%m+m)%m,m) , (x%m+m)%m , m))%m; } if(c>=mx) printf("%lld\n",c); else printf("%lld\n",c+m*((mx-c-1)/m+1)); } return 0; }