这道题写了好久,因为一个略傻缺的错误测了好久。。。
这道题我们需要抓住到一点:前面的糖糖会不会被消灭,只和后面的糖糖有关,所以,我们获取信息的顺序应该是从后开始,然后让前面的和后面比较。由于我们只需要知道会不会被消灭,所以,我们要的是后面的糖糖种的、类似最大值的东西。
那么,假设我们要比较两个糖糖i和j(i<j),那么,我们确定i会不会被消灭的时候,我们比较的式子就是:
b[i]+sum[j]-sum[i-1]<=>b[j]+c[j]
我们变一下式,就变成:
b[i]-sum[i-1]<=>b[j]+c[j]-sum[j]
这时候,式子右边的就是我们要找的定值。那么,每次查询一个位置的时候,计算一下这个位置的b[j]+c[j]-sum[j]与目前该队里的最大值做比较,选择是否替代。
另外,还需要几个特判:有对手队还没有出现,可以continue跳过判断。如果这是本队出现的第一个,就直接取值等等。就直接看代码吧。

#include <iostream>
#include <cstdio>
#include <map>
#include <cstring>
#include <climits>
const int INF = 0x3F3F3F3F;
#define MEM(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(register int i=a;i<=b;++i)
#define per(i,a,b) for(register int i=b;i>=a;--i)
using namespace std;
typedef long long ll;
const int maxn=1000000+10;
int a[maxn],b[maxn],c[maxn];
int n,m;
int sum[maxn];

int read()
{
    char ch=getchar();int x=0,f=1;
    while(ch<'0' || ch>'9')   {if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

int main()
{
    /*
    6
    5 5
    0 0
    0 3
    0 4
    1 4
    1 1
    1
    2
    3
    4
    5
    */
    //freopen("inin.txt","r",stdin);
    int _;
    _=read();
    while(_--){
        MEM(c);
        n=read(),m=read();
        ll dec=0;
        ll p0=-1,p1=-1;
        rep(i,1,n){
            a[i]=read();
            b[i]=read();
        }
        rep(i,1,m){
            int t;
            //scanf("%d",&t);
            t=read();
            c[t]++;
        }
        rep(i,1,n){
            sum[i]=sum[i-1]+c[i];
        }
        per(i,1,n){
            if(a[i]==1){
                if(p1==-1){
                    p1=i;
                }
                if(b[p1]+c[p1]-sum[p1]<=b[i]+c[i]-sum[i]){
                    p1=i;
                }
                if(p0==-1) continue;
                if(b[i]+sum[p0]-sum[i-1]<b[p0]+c[p0]){
                    dec++;
                }
            }
            else if(a[i]==0){
                if(p0==-1){
                    p0=i;
                }
                if(b[i]+c[i]-sum[i]>=b[p0]+c[p0]-sum[p0]){
                    p0=i;
                }
                if(p1==-1) continue;
                if(b[i]+sum[p1]-sum[i-1]<b[p1]+c[p1]){
                    dec++;
                }
            }
        }
        printf("%d\n",n-dec);
    }
    return 0;
}