题目大意
存在 个人,每个人分配在0,1两个阵营之中,还有对应自己的能力值
存在 次操作,每次输入
把
能力值+1。
解决方法
如果从前往后统计,对于每个人,需要在 秒之后才可以被增幅,要考虑的因素比较多。
换个思路,我们知道每 个人在他行动阶段只会对前
个人产生影响。后面的人是不存在影响的,所以如果后面存在能力值比第
个人能力值高的,第
个人就会牺牲。
这样我们先考虑全部玩家先增幅完毕,计算到能力值的最大值。从后往前遍历,因为这样的话如果这个人小于另一队当前的最大值,并且这个是被增幅之后的,仍小于最大值,说明这个人就将被另一队最大值淘汰。
时间复杂度O(N)
Code
#include <bits/stdc++.h>
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
typedef long long ll;
inline int read() {
int s = 0, w = 1; char ch = getchar();
while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
return s * w;
}
const int N = 5e4 + 7;
struct Node {
int x;
int y;
}a[N];
int b[N];
int main() {
int T = read();
while (T--) {
memset(b, 0, sizeof(b));
int n = read(), m = read();
for (int i = 1; i <= n; ++i)
a[i].x = read(), a[i].y = read();
for (int i = 1; i <= m; ++i) {
int k = read();
++b[k];
}
// 后缀和
for (int i = n; i; --i) {
b[i] += b[i + 1];
a[i].y += b[i];
}
int max0 = 0, max1 = 0, ans = n; // ans为存活人数
for (int i = n; i; --i) {
if (a[i].x == 0) {
max0 = max(max0, a[i].y);
if (max1 > a[i].y)
--ans;
}
else {
max1 = max(max1, a[i].y);
if (max0 > a[i].y)
--ans;
}
}
printf("%d\n", ans);
}
return 0;
} 
京公网安备 11010502036488号