链接:https://ac.nowcoder.com/acm/problem/14583
来源:牛客网
题目描述
从前,有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
题意:每颗糖有一个能力值b[i],在第i秒时,i可以消灭在i之前且和i不同组且能力值比i小的糖,在c[i]秒时从1到c[i]所有的糖的能力值都加1。
题记:由于c[i]是不会影响到当前第i秒的结果的,所以可以直接把所有1到c[i]的能力值都加上。然后从后往前遍历,记录下0组和1组的最大值,如果当前的能力值大于或等于另一组的最大值,那么当前这个数是不会被消灭的,ans++。(从后往前推,用纸笔模拟一下这个过程比较好理解)。
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10;
struct node{
int f,val;
}node[N];
int c[N];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T;
cin>>T;
while(T--){
int n,m;
cin>>n>>m;
memset(c,0,sizeof(c));
for(int i=0;i<n;i++)
cin>>node[i].f>>node[i].val;
int x;
for(int i=0;i<m;i++){
cin>>x;
c[0]++;
c[x]--;
}
int s=0;
for(int i=0;i<n;i++){
s+=c[i];
node[i].val+=s;
}
/*
for(int i=0;i<n;i++){
cout<<node[i].f<<' '<<node[i].val<<endl;
}
*/
int ans=0,max1=-1,max2=-1;
for(int i=n-1;i>=0;i--){
if(node[i].f){
max1=max(max1,node[i].val);
if(node[i].val>=max2)
ans++;
}
else{
max2=max(max2,node[i].val);
if(node[i].val>=max1)
ans++;
}
}
cout<<ans<<endl;
}
return 0;
}