#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e6+5;
int n,m,p,q,a1[N],a2[N],b[N],c[N],l,r,mid,to,top,cnt;
struct node{
int x,y;
}a[N],d[N];
priority_queue<node>q1;
bool operator < (node u,node v){return u.y>v.y;}
bool cmp1(node u,node v){return u.x>v.x;}
bool cmp2(int x,int y){return x>y;}
bool cmp3(node u,node v){return u.y<v.y;}
bool check(){
to=1;
for(int i=1;i<=p;i++){
while(a[to].x>=a1[i]&&to<=m) q1.push(a[to]),to++;
for(int j=1;j<=mid&&!q1.empty();j++) q1.pop();
}
top=0;
while(!q1.empty()) d[++top]=q1.top(),q1.pop();
while(to<=m) d[++top]=a[to],to++;
sort(d+1,d+top+1,cmp3),cnt=1;
for(int i=1;i<=q;i++)
for(int j=1;j<=mid&&cnt<=top&&d[cnt].y<=a2[i];j++)
cnt++;
cnt--;
if(cnt>=(ll)top-(ll)(n-p-q)*mid) return 1;
return 0;
}
int main(){
// freopen("taste.in","r",stdin);
// freopen("taste.out","w",stdout);
scanf("%d%d%d%d",&n,&m,&p,&q);
for(int i=1;i<=m;i++) scanf("%d%d",&a[i].x,&a[i].y);
sort(a+1,a+m+1,cmp1);
for(int i=1;i<=p;i++) scanf("%d",&a1[i]);
sort(a1+1,a1+p+1,cmp2);
for(int i=1;i<=q;i++) scanf("%d",&a2[i]);
sort(a2+1,a2+q+1);
mid=m;
if(!check()) return puts("-1"),0;
l=1,r=m;
while(l<r){
mid=l+r>>1;
if(check()) r=mid;
else l=mid+1;
}
printf("%d\n",r);
return 0;
}
在 luogu AC 了,但是今天模拟赛 Wa 55pts
检查发现:
bool operator < (node u,node v){return u.y>v.y;}
应改为:
bool operator < (node u,node v){return u.y<v.y;}
原来是大根堆当作小根堆用了,我承认我很菜所以错了很智障的地方