题意
有个人,分成2个队伍,每个人都有一个战力值
第秒,第个人会消灭前面不属于同一个队伍,且战力值小于他的所有人。
与此同时,有m次机会,第每次前个人的战力都会增加1,问你第秒存活的人数与此同时,有m次机会,每次前个人的战力都会增加1,问你第n秒存活的人数。
分析
从后向前遍历,若当前为第个人,那只有前个人会受到影响。对于次的发功,可以维护一个后缀和,然后每个人的实际战斗力为。如此只需要维护两个队伍的最大值,如果第个人的战斗力比另外一个队伍的最大值小,第个人就会消灭掉。
时间复杂度:
参考代码
#include <bits/stdc++.h> using namespace std; #define FAST_IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0) typedef long long ll; int main(void) { FAST_IO; int t; cin >> t; while (t--) { int n, m; cin >> n >> m; vector<pair<int, ll>> a(n + 1); vector<int> c(n + 1, 0); for (int i = 1; i <= n; i++) { cin >> a[i].first >> a[i].second; } for (int i = 0; i < m; i++) { int x; cin >> x; c[x]++; } ll mx1 = 0, mx2 = 0; ll ans = 0; for (int i = n; i >= 1; i--) { if (i != n) c[i] += c[i + 1]; a[i].second += c[i]; if (a[i].first == 0) { mx1 = max(mx1, a[i].second); if (a[i].second >= mx2) { ans++; } } else { mx2 = max(mx2, a[i].second); if (a[i].second >= mx1) { ans++; } } } cout << ans << endl; } return 0; }