传送门

题意

个人,分成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;
}