糖糖别胡说,我真的不是签到题目
糖糖别胡说,我真的不是签到题目
题目分析:
- 涉及算法:模拟,后缀和
- 根据题意可知,分两组(0,1),能量大的可以消灭另一组比它能量小的,求剩余的数量
- 对于一个时间点,用后缀和数组s[]存储每个时间点数量为1,利用后缀和,求出每个时间点总共加的能量值。
- 从后往前,记录两个组的最大值与当前值比较,求出剩余个数
注意:
1.输入t组,需要初始化数组s[]
代码如下:
#include<bits/stdc++.h> using namespace std; #define mm(a,x) memset(a,x,sizeof a) #define mk make_pair #define ll long long #define pii pair<int,int> #define inf 0x3f3f3f3f #define lowbit(x) (x) & (-x) const int N = 50010; int t; int n,m; struct Node { ll a,b; } node[N]; int s[N]; int main() { cin >> t; while(t -- ) { mm(s,0); cin >> n >> m; for(int i = 1; i <= n; i ++ ) { ll a,b; cin >> a >> b; node[i] = {a,b}; } for(int i = 1; i <= m; i ++ ) { int x; cin >> x; s[x] ++; } for(int i = n; i >= 1; i -- ) s[i] += s[i + 1],node[i].b += s[i]; ll m1 = 0,m2 = 0,cnt = n; for(int i = n; i >= 1; i -- ) { if(node[i].a) { m1 = max(m1,node[i].b); if(m2 > node[i].b) cnt--; } else { m2 = max(m2,node[i].b); if(m1 > node[i].b) cnt--; } } cout<<cnt<<endl; } return 0; }