Final Boss(二分)

You are facing the final boss in your favorite video game. The boss enemy has \(h\) health. Your character has \(n\) attacks. The \(i\)'th attack deals \(a_i\) damage to the boss but has a cooldown of \(c_i\) turns, meaning the next time you can use this attack is turn \(x + c_i\) if your current turn is \(x\). Each turn, you can use all attacks that are not currently on cooldown, all at once. If all attacks are on cooldown, you do nothing for the turn and skip to the next turn.

Initially, all attacks are not on cooldown. How many turns will you take to beat the boss? The boss is beaten when its health is \(0\) or less.

Input

The first line contains \(t\) (\(1 \leq t \leq 10^4\))  – the number of test cases.

The first line of each test case contains two integers \(h\) and \(n\) (\(1 \leq h, n \leq 2 \cdot 10^5\)) – the health of the boss and the number of attacks you have.

The following line of each test case contains \(n\) integers \(a_1, a_2, ..., a_n\) (\(1 \leq a_i \leq 2 \cdot 10^5\)) – the damage of your attacks.

The following line of each test case contains \(n\) integers \(c_1, c_2, ..., c_n\) (\(1 \leq c_i \leq 2 \cdot 10^5\)) – the cooldown of your attacks.

It is guaranteed that the sum of \(h\) and \(n\) over all test cases does not exceed \(2 \cdot 10^5\).

Output

For each test case, output an integer, the minimum number of turns required to beat the boss.

题义:
有一个血量为 h 的BOSS, 在每个时间内可以使用所有种类的攻击,每个种类造成 ai 点伤害, 有 ci 个时间的冷却.
问最少多长时间能击败BOSS

因为冷却最多为 2E5 , 血量最多为 2E5 , 伤害最低为 1, 所以时间最多为 4E10
在 0 ~ 1E11 这个区间进行二分查找, 如果当前的时间能消灭BOSS, 就把 hi 设置为当前时间, 去找更低的时间能不能消灭BOSS

#include<bits/stdc++.h>
#define L(i, j, k) for(int i = (j); i <= (k); ++i)
#define R(i, j, k) for(int i = (j); i >= (k); --i)
#define sz(a) ((int) (a).size())
#define pb emplace_back
#define me(a, x) memset(a, x, sizeof(a))
#define vi vector<int>
#define ull unsigned long long
#define i128 __int128
#define TEST 
#define TESTS int T; cin >> T; while(T--)
#define INF 0x3f3f3f3f3f3f3f3f
#define int long long
const int N = 1E+6;
using namespace std;
void Main() {
	int h, n;
	cin >> h >> n;
	vi a(n), c(n);
	L(i, 0, n-1) cin >> a[i];
	L(i, 0, n-1) cin >> c[i];
	int lo = 0, hi = 1E11;
	while(lo < hi) {
		int x = lo + ((hi - lo) >> 1); // 左 + (右 - 左) / 2
		int dmg = 0;
		L(i, 1, n-1) {
			dmg += (x + c[i] - 1) / c[i]; // 总伤害等于各种攻击在 x 时间内能造成的伤害总和
			if(dmg >= h) break;
		}
		if(dmg >= h) { // 当前时间能杀死 , 看看更少的时间能不能杀死
			hi = x;
		}
		else {
			lo = x + 1;
		}
	}
	cout << lo << endl;
}
signed main() {
	ios :: sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	TESTS Main();
	return 0;
}
posted @ 2024-12-03 16:43  shen_kong  阅读(40)  评论(0)    收藏  举报