糖糖别胡说,我真的不是签到题目
题解: 核心就是满足条件,i<j and a[i]!=a[j] and b[i]<b[j] ; 另外有个附加属性,有一些发功的时间 i 第i秒会给在第i秒及以前出现的b[i]+1,
用一个sum[i]数组表示在此时间受到发功影响的次数的总和。那么问题就是变为 在i<j的条件下,b[i]+sum[j]-sum[i-1]<b[j]+sum[j]-sum[j-1];
两边同时去掉sum[j],即b[i]-sum[i-1]<b[j]-sum[j-1];ps:发功时间是第i秒的话,前面i-1秒的元素不会被影响。
只有两个组别,0和1,可以用a[i]^1来表达不同组。从后往前扫描,记录每组的最大值,与不同组的比较即可。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5;
int a[maxn];
int b[maxn];
int sum[maxn];
int ans;
int main(){
int t,n,m,f;cin>>t;
while(t--){
ans=0;
fill(sum,sum+maxn,0);
fill(a,a+maxn,0);
fill(b,b+maxn,0);
cin>>n>>m;
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i],&b[i]);
}
for(int i=1;i<=m;i++){
scanf("%d",&f);
sum[f]++;
}
for(int i=1;i<=n;i++){
sum[i]+=sum[i-1];
b[i]-=sum[i-1];
}
int ans=n;
int c[2];c[0]=-0x3f3f3f;c[1]=-0x3f3f3f;
for(int i=n;i>=1;i--){
if(b[i]<c[a[i]^1])ans--;
c[a[i]]=max(c[a[i]],b[i]);
}
cout<<ans<<endl;
}
return 0;
}