解析:
二分,每次check次数。
每次check,前mid个数已被标记为1,所以我们需要遍历所有区间,查看是否存在一个区间,他包含的1的个数严格大于0的个数(即是否大于区间长度的一半)
数据量1e5,二分mid使用了logn,所以check的复杂度必须维持在 n---nlogn 之间,操作是单点修改和区间查询,显然树状数组维护某区间1的个数即可。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int t,n,m,q,x[N],y[N],a[N];
int c[N];
int lowbit(int x){
return x&-x;
}
void add(int k){
for(int i=k;i<=n;i+=lowbit(i)) c[i]+=1;
}
int sum(int x,int y){
int res=0;
for(int i=y;i;i-=lowbit(i)) res+=c[i];
for(int i=x-1;i;i-=lowbit(i)) res-=c[i];
return res;
}
bool check(int mid){
for(int i=1;i<=n;i++) c[i]=0;
for(int i=1;i<=mid;i++) add(a[i]);
for(int i=1;i<=m;i++){
if(sum(x[i],y[i])>(y[i]-x[i]+1)/2) return true;
}
return false;
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&x[i],&y[i]);
}
scanf("%d",&q);
for(int i=1;i<=q;i++){
scanf("%d",&a[i]);
}
int l=1,r=q+1;
while(l<r){
int mid=l+r>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
if(r==q+1) puts("-1");
else printf("%d\n",r);
}
return 0;
}