题意
有N 个人, M 个位置, 第i 个人想要坐再[1;Li] 或[Ri;M] 之
间, 求最少有多少人不能被满足. 不一定每个人都要安排位置.
题解
显然是一个二分图
然后根据hall定理
一个二分图的最大匹配数是n−max(|S|−|S′|)n−max(|S|−|S′|)
后面那个就是失配数
然后显然地,|S′||S′|显然就是一段[1,L],[R,n][1,L],[R,n]
考虑枚举一个L,RL,R
那么我们可以得到这个东西可以满足这个的点数是aa
那么答案就是
a就是一个点(R,L)(R,L)为原点的坐标轴,第四象限的点,包括两条坐标轴
这个显然可以单调地维护RR,然后剩下的用线段树维护
CODE:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=200005;
int n,m;
struct qq{int x,y;}s[N];
int ans=0;
bool cmp (qq x,qq y){return x.y<y.y;}
struct qt
{
int l,r;
int s1,s2;
int c;
int lzy;
}tr[N*2];int num;
void update (int now)
{
int s1=tr[now].s1,s2=tr[now].s2;
tr[now].c=max(tr[s1].c,tr[s2].c);
}
void bt(int l,int r)
{
int a=++num;
tr[a].l=l;tr[a].r=r;
if (l==r) {tr[a].c=l;return ;}
int mid=(l+r)>>1;
tr[a].s1=num+1;bt(l,mid);
tr[a].s2=num+1;bt(mid+1,r);
update(a);
}
void push_down (int now)
{
int s1=tr[now].s1,s2=tr[now].s2;
int lzy=tr[now].lzy;tr[now].lzy=0;
tr[s1].lzy+=lzy;tr[s1].c+=lzy;
tr[s2].lzy+=lzy;tr[s2].c+=lzy;
}
void change (int now,int l,int r,int x)
{
if (l>r) return ;
if (tr[now].l==l&&tr[now].r==r)
{
tr[now].lzy+=x;tr[now].c+=x;
return ;
}
push_down (now);
int s1=tr[now].s1,s2=tr[now].s2;
int mid=(tr[now].l+tr[now].r)>>1;
if (r<=mid) change(s1,l,r,x);
else if (l>mid) change(s2,l,r,x);
else change(s1,l,mid,x),change(s2,mid+1,r,x);
update(now);
}
int main()
{
scanf("%d%d",&n,&m);
for (int u=1;u<=n;u++) scanf("%d%d",&s[u].y,&s[u].x);
sort(s+1,s+1+n,cmp);
bt(0,m+1);
int now=1;
for (int u=0;u<=m;u++)
{
while (now<=n&&s[now].y<=u)
{
change(1,1,s[now].x,1);
now++;
}
ans=max(ans,-m-u-1+tr[1].c);
}
printf("%d\n",max(ans,n-m));
return 0;
}