对于这一位置的糖糖能存活,当且仅当他编号后面的另一个组的糖糖的最大值≤它
对于发功,发功的作用会对1~i产生影响,也就是提高前面的能力值,我们大可以直接处理出来发功次数用完后的能力值。
为什么可以这样?因为如果前面的糖糖会被提前干掉,发功产生的影响其实是对前面的都进行增加的,是不影响前面会被打掉的人,只会影响前面没被打掉的是否会被该位置后面的干掉。
那么,对发功处理一个后缀和,倒序遍历所有糖糖更新能力值,同时更新两个组的最大值,比较当前位置的能力与另一个组的最大值即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define x first
#define y second
pair<ll,ll> a[1<<16];
ll cnt[1<<16];
int main(){
    int t;cin>>t;
    while(t--){
        int n,m;cin>>n>>m;
        for(int i=1;i<=n;i++) cin>>a[i].x>>a[i].y,cnt[i]=0;
        for(int i=1;i<=m;i++){
            int q;cin>>q;
            cnt[q]++;
        }

        ll ma0=-1,ma1=-1;
        int ans=0;
        for(int i=n;i;i--){
           cnt[i]+=cnt[i+1];///后缀和
           a[i].y+=cnt[i];//更新当前糖糖的能力值
            if(a[i].x==0){//组别为0
                if(a[i].y>=ma1) ans++;//该位置后面的组别为1的最大值的是否≤当前位置的能力值
                ma0=max(ma0,a[i].y);//更新组别0的最大值
            }
            else
            {
                if(a[i].y>=ma0) ans++;//该位置后面的组别为0的最大值的是否≤当前位置的能力值
                 ma1=max(ma1,a[i].y);//更新组别1的最大值
            }
        }
        cout<<ans<<endl;
    }
}