糖糖别胡说,我真的不是签到题目
糖糖别胡说,我真的不是签到题目
https://ac.nowcoder.com/acm/problem/14583
题意
n只糖糖分为两组,每只糖糖有一个能力值b[i]。第i秒时,第i只糖糖可以消灭排在他前面且和他不是一组的糖糖。娇姐可以法攻m次,每次发功给定时间t,第t秒后b[1]...b[t]的值都加1。问第n秒后还剩几只糖糖。
思路
理解题意理解了好一会~ ~ 。主要困难点在于m次发功操作,我们可以讨论下发功操作带来的影响。对于一次在第t秒的发功操作,并不会改变前t个糖糖的相对大小,只可能改变前t个糖糖和后面糖糖的相对大小。那么我们可不可以在开始的时候就把b[1]..b[t]先加上1呢?答案是肯定的(参考前面)。这样我们就可以先算出糖糖的最后的能力(可以差分处理),在从后往前处理,判定糖糖会不会被消灭,更新两个组中糖糖的最大能力值。
复杂度
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e4 + 10;
int val[2];
int a[maxn], b[maxn], d[maxn];
int main()
{
int T, n, m;
for(cin >> T; T--; ){
cin >> n >> m;
memset(d, 0, sizeof d);
val[0] = val[1] = 0;
for(int i = 1; i <= n; i++){
cin >> b[i] >> a[i];
}
for(int i = 0; i < m; i++){
int k;
cin >> k;
d[0]++; d[k + 1]--;
}
for(int i = 1; i <= n; i++){
d[i] += d[i - 1];
a[i] = a[i] + d[i];
}
int ans = n;
for(int i = n; i >= 1; i--){
if(a[i] < val[1 - b[i]]){
ans--;
}
val[b[i]] = max(val[b[i]], a[i]);
}
cout << ans << endl;
}
return 0;
}
