题目描述
从前,有n只萌萌的糖糖,他们分成了两组一起玩游戏。他们会排成一排,第i只糖糖会随机得到一个能力值bi。从第i秒的时候,第i只糖糖就可以消灭掉所有排在他前面的和他不是同一组的且能力值小于他的糖糖。
为了使游戏更加有趣,糖糖的爸爸,娇姐,会发功m次,第i次发功的时间为ci,则在第ci秒结束后,b1,b2,…,bci都会增加1.
现在,娇姐想知道在第n秒后,会有多少只糖糖存活下来。
输入描述:
第一行只有一个整数T(T<6),表示测试数据的组数。
第二行有两个整数n,m。表示糖糖的个数以及娇姐发功的次数。(1<=n<=50000,1<=bi<=1000000)
第三行到n+2行,每行有两个整数ai,bi,表示第i只糖糖属于那一组以及他的能力值。(0<=ai<=1,1<=bi<=1000000)
第n+3行到第n+m+2行,每行有一个整数ci,表示GTW第i次发功的时间.(1<=ci<=n)
输出描述:
总共T行,第i行表示第i组数据中,糖糖存活的个数。
示例1
输入
复制
1 4 3 0 3 1 2 0 3 1 1 1 3 4
输出
复制
3
原谅我太菜了,这道题一直死活不AC,实际上就一个差分方程,然后从后往前遍历就好了,选择他后面的最大值保存,然后进行比较即可。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;
int n, m, t;
struct node {
int x, y;
};
node st[50010];
int b[50001];
int main() {
scanf("%d", &t);
while(t--) {
memset(b, 0, sizeof(b));
int cnt = 0;
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%d %d", &st[i].x, &st[i].y);
for (int i = 0; i < m; i++) {
int ts;
scanf("%d", &ts);
b[1]++;
b[++ts]--;
}
for (int i = 1; i <= n; i++) {
b[i] += b[i - 1];
st[i].y += b[i];
}
int max0 = -100000, max1 = -1;
for (int i = n; i > 0; i--) {
if (st[i].x == 0) {
max0 = max(st[i].y, max0);
if (max1 <= st[i].y)
cnt++;
}
else {
max1 = max(max1, st[i].y);
if (max0 <= st[i].y)
cnt++;
}
}
printf("%d\n", cnt);
}
return 0;
}