uoj396 [NOI2018]屠龍勇士
[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]屠龍勇士