后缀数组写起来简单,理解也比较简单。如果在原来的基础之上发功,就算开始发功的人收益但当后续的发功结束后该来的终究会来,之前小于他的糖糖也会被灭掉,所以从后往前是可以的,还容易维护一些
#include <bits/stdc++.h>
using namespace std;
#define ll long long
struct node {
ll a,b;
}m[50007];
ll c[1000007]={0};///后缀小数组
int main()
{
ll t;
scanf("%lld",&t);
while (t--)
{
ll n,w;
memset(c,0,sizeof(c));///初始化
scanf("%lld%lld",&n,&w);
for (register int i=1;i<=n;++i)
{
scanf("%lld%lld",&m[i].a,&m[i].b);
}
for (register int i=1;i<=w;++i)
{
int x;
scanf("%d",&x);
++c[x];
}
ll ans=0;
ll maxn_1=-1;
ll maxn_0=-1;
for (register int i=n;i>=1;--i)
{
c[i]+=c[i+1];///累计发功量
m[i].b+=c[i];///发功
if (m[i].a){
if(maxn_1<m[i].b)///更新该组最大值
{
maxn_1=m[i].b;
}
if (m[i].b<maxn_0)///比较后面有无其他组最大值大于他
++ans;
}
else
{
if(maxn_0<m[i].b)
maxn_0=m[i].b;
if (m[i].b<maxn_1)
++ans;
}
}
printf("%lld\n",n-ans);///所有减去死亡的 正难则反
}
return 0;
}



京公网安备 11010502036488号