class Solution { public: long long totalScore(...
Erstellt am: 7. Dezember 2025
Beantwortet mit GPT-5.1 Thinking von Chat01
Erstellt am: 7. Dezember 2025
Beantwortet mit GPT-5.1 Thinking von Chat01
class Solution {
public:
long long totalScore(int hp, vector<int>& damage, vector<int>& requirement) {
}
};©leetcode
You are given a positive integer hp and two positive 1-indexed integer arrays damage and requirement.
There is a dungeon with n trap rooms numbered from 1 to n. Entering room i reduces your health points by damage[i]. After that reduction, if your remaining health points are at least requirement[i], you earn 1 point for that room.
Let score(j) be the number of points you get if you start with hp health points and enter the rooms j, j + 1, ..., n in this order.
Return the integer score(1) + score(2) + ... + score(n), the sum of scores over all starting rooms.
Note: You cannot skip rooms. You can finish your journey even if your health points become non-positive.
Example 1:
Input: hp = 11, damage = [3,6,7], requirement = [4,2,5]
Output: 3
Explanation:
score(1) = 2, score(2) = 1, score(3) = 0. The total score is 2 + 1 + 0 = 3.
As an example, score(1) = 2 because you get 2 points if you start from room 1.
You start with 11 health points.
Enter room 1. Your health points are now 11 - 3 = 8. You get 1 point because 8 >= 4.
Enter room 2. Your health points are now 8 - 6 = 2. You get 1 point because 2 >= 2.
Enter room 3. Your health points are now 2 - 7 = -5. You do not get any points because -5 < 5.
Example 2:
Input: hp = 2, damage = [10000,1], requirement = [1,1]
Output: 1
Explanation:
score(1) = 0, score(2) = 1. The total score is 0 + 1 = 1.
score(1) = 0 because you do not get any points if you start from room 1.
You start with 2 health points.
Enter room 1. Your health points are now 2 - 10000 = -9998. You do not get any points because -9998 < 1.
Enter room 2. Your health points are now -9998 - 1 = -9999. You do not get any points because -9999 < 1.
score(2) = 1 because you get 1 point if you start from room 2.
You start with 2 health points.
Enter room 2. Your health points are now 2 - 1 = 1. You get 1 point because 1 >= 1.
Constraints:
1 <= hp <= 109
1 <= n == damage.length == requirement.length <= 105
1 <= damage[i], requirement[i] <= 104©leetcode
You can think of this as:
instead of simulating from every starting room j, let each room i ask:
“For how many starting rooms
j ≤ ido I give a point?”
Then sum those contributions over all rooms i.
Let
S[i] = damage[1] + ... + damage[i] (prefix sums, with S[0] = 0).If we start at room j and look at room i (j ≤ i):
j..i is S[i] - S[j-1].i is:
i gives a point iff:
Define
So for a fixed i, all starting rooms j (with 1 ≤ j ≤ i) that get a point at room i are exactly those with:
S[j-1] ≥ T[i], where j-1 ranges over 0..i-1.So room i contributes:
count of t in [0..i-1] such that S[t] >= T[i]
to the total answer.
We can process rooms i = 1..n left to right and maintain all S[0], S[1], ..., S[i-1] in a data structure that lets us count how many of them are ≥ some value.
Values S[t] are up to about 1e9, so we compress them.
Steps:
S[0..n].vals of all S[t].S[t] to an index in [1..m] (where m = vals.size()).bit of size m, where:
bit[idx(S[t])] stores how many times this prefix sum value has appeared (we add 1 for each S[t] we insert).i, we:
S[0..i-1] into the BIT.i.To count how many S[t] (among inserted) are ≥ T[i]:
pos = lower_bound(vals.begin(), vals.end(), T[i]) - vals.begin();
pos is 0-based index of first vals[pos] >= T[i].< pos have vals[k] < T[i].S[t] < T[i] is fenwick.sum(pos) (since Fenwick is 1-based and pos elements are < T[i]).totalInserted = i.S[i] into the BIT for future iterations.Complexity:
O(n log n)O(n)cpp#include <bits/stdc++.h> using namespace std; struct Fenwick { int n; vector<long long> bit; Fenwick(int n) : n(n), bit(n + 1, 0) {} void add(int i, long long delta) { for (int x = i; x <= n; x += x & -x) { bit[x] += delta; } } long long sum(int i) { long long s = 0; for (int x = i; x > 0; x -= x & -x) { s += bit[x]; } return s; } }; class Solution { public: long long totalScore(int hp, vector<int>& damage, vector<int>& requirement) { int n = (int)damage.size(); // 1. Prefix sums S[0..n] vector<long long> pref(n + 1, 0); for (int i = 1; i <= n; ++i) { pref[i] = pref[i - 1] + (long long)damage[i - 1]; } // 2. Coordinate compress all prefix sums vector<long long> vals = pref; sort(vals.begin(), vals.end()); vals.erase(unique(vals.begin(), vals.end()), vals.end()); int m = (int)vals.size(); // Map each prefix to its compressed index (1-based for Fenwick) vector<int> idx(n + 1); for (int i = 0; i <= n; ++i) { idx[i] = int(lower_bound(vals.begin(), vals.end(), pref[i]) - vals.begin()) + 1; } Fenwick fw(m); long long ans = 0; // Insert S[0] fw.add(idx[0], 1); // 3. Process each room i as contributor for (int i = 1; i <= n; ++i) { long long T = (long long)requirement[i - 1] + pref[i] - (long long)hp; // Find first prefix sum >= T int pos = int(lower_bound(vals.begin(), vals.end(), T) - vals.begin()); long long less = (pos == 0 ? 0 : fw.sum(pos)); long long totalInserted = i; // S[0..i-1] inserted long long geq = totalInserted - less; ans += geq; // Insert S[i] for future rooms fw.add(idx[i], 1); } return ans; } };
This matches the examples and passes random brute-force checks.