糖糖别胡说,我真的不是签到题目

题目分析:

  1. 涉及算法:模拟,后缀和
  2. 根据题意可知,分两组(0,1),能量大的可以消灭另一组比它能量小的,求剩余的数量
  3. 对于一个时间点,用后缀和数组s[]存储每个时间点数量为1,利用后缀和,求出每个时间点总共加的能量值。
  4. 从后往前,记录两个组的最大值与当前值比较,求出剩余个数

注意:

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;
}