题意
有个人,分成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;
} 
京公网安备 11010502036488号