Educational Codeforces Round 125 D. For Gamers. By Gamers.
阿新 • • 發佈:2022-03-23
題目大意
有 \(n(1\leq n\leq 3\times 10^5)\) 種單位,\(C(1\leq C\leq 10^6)\) 個金幣,只能選擇一種單位進行招募,在總花費不超過 \(C\) 的情況下,可以招募若干個,每種單位 \(i\) 有單價 \(c_{i}(1\leq c_{i}\leq C)\) , 攻擊力 \(d_{i}\) , 生命值 \(h_{i}(1\leq d_{i},h_{i}\leq 10^6)\) 。需要擊敗 \(m\) 個怪物,每個怪物 \(j\) 有攻擊力 \(D_{j}(1\leq D_{j}\leq 10^6)\), 生命值 \(H_{j}(1\leq H_{j}\leq10^{12})\)
思路
對於招募了 \(k\) 個第 \(i\) 種單位, 第 \(j\) 種怪物,滿足要求的條件為 \(\frac{H{j}}{kd_{i}}<\frac{h_{i}}{D_{j}}\) ,也就是 \(kd_{i}h_{i}>D_{j}H_{j}\) 。因為只能招募一個種單位,於是我們可以預處理出 \(B[\space]\) 為每個價格 \(kc_{i}\) 下,能夠獲得的最大 \(kd_{i}h_{i}\)
程式碼
#include<bits/stdc++.h> #include<unordered_map> #include<unordered_set> using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int, int> PII; #define all(x) x.begin(),x.end() #define int LL //#define lc p*2+1 //#define rc p*2+2 #define endl '\n' #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #pragma warning(disable : 4996) #define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0) const double eps = 1e-8; const LL mod = 1000000007; const LL MOD = 998244353; const int maxn = 1000010; LL N, C, M; LL A[maxn], B[maxn], c[maxn], d[maxn], h[maxn], D[maxn], H[maxn]; void solve() { for (int i = 1; i <= N; i++) A[c[i]] = max(A[c[i]], d[i] * h[i]); for (int i = 1; i <= C; i++) { if (A[i]) { for (int j = 1; i * j <= C; j++) B[i * j] = max(B[i * j], A[i] * j); } } for (int i = 1; i <= C; i++) B[i] = max(B[i], B[i - 1]); for (int i = 1; i <= M; i++) { LL J = H[i] * D[i]; LL ans = upper_bound(B + 1, B + C + 1, J) - B; cout << (ans > C ? -1 : ans) << ' '; } cout << endl; } signed main() { IOS; cin >> N >> C; for (int i = 1; i <= N; i++) cin >> c[i] >> d[i] >> h[i]; cin >> M; for (int i = 1; i <= M; i++) cin >> D[i] >> H[i]; solve(); return 0; }