loj#6062. 「2017 山东一轮集训 Day2」Pair
首先这题对于 $a[l,l+m-1]$ 能够成功匹配,当且仅当去连边,然后能形成完美匹配。
但是边数可能到 $m^2$ 的级别,所以跑不了 dinic,但我们只需要判断是否有。
于是,考虑 hall 定理,即对于二分图一部的子集 $S$,每个点在另一部连得边的并集 $S'$,有 $|S| \le |S'|$,则该二分图有完美匹配。
考虑线段树维护前缀 $could_i-i$。
$$[1,r],r\le could_r$$
$$[l,r],l-1\le could_{l-1},r\le could_{r}$$
$$r-(l-1)\le could_{r}-could_{l-1}$$
$$could_i-i\ge0$$
对于一部的点集动态,就不能先 $build$ 了。
实际上 $b$ 升序/顺序没有影响。处理麻烦或简单而已。
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cmath>
#include <queue>
#include <map>
#define ll long long
using namespace std;
int rd() {
int f=1,sum=0; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return sum*f;
}
ll lrd() {
ll f=1,sum=0; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return sum*f;
}
#define ls (cur<<1)
#define rs (ls|1)
const int N=(int)(1.5e5+5);
int mi[N<<2],tag[N<<2];
int n,m,h,a[N],b[N];
void push_up(int cur) {
mi[cur]=min(mi[ls],mi[rs]);
}
void push_down(int cur) {
if(!tag[cur]) return ;
tag[ls]+=tag[cur]; tag[rs]+=tag[cur];
mi[ls]+=tag[cur]; mi[rs]+=tag[cur];
tag[cur]=0;
}
void build(int cur,int l,int r) {
mi[cur]=0x3f3f3f3f;
if(l==r) return mi[cur]=-l,void();
int mid=(l+r)>>1;
build(ls,l,mid); build(rs,mid+1,r);
push_up(cur);
}
void update(int cur,int l,int r,int cl,int cr,int v) {
if(cl<=l&&r<=cr) {
tag[cur]+=v; mi[cur]+=v; return ;
}
push_down(cur);
int mid=(l+r)>>1;
if(cl<=mid) update(ls,l,mid,cl,cr,v);
if(cr>mid) update(rs,mid+1,r,cl,cr,v);
push_up(cur);
}
int main() {
n=rd(); m=rd(); h=rd();
for(int i=1;i<=m;i++) b[i]=rd();
for(int i=1;i<=n;i++) a[i]=rd();
sort(b+1,b+1+m);
build(1,1,m);
int ans=0; // a[i]+b[i]>=h a[i]-h>=b[i]
for(int i=1;i<=m;i++) {
int p=lower_bound(b+1,b+1+m,h-a[i])-b;
if(p<=m) update(1,1,m,p,m,1);
}
ans+=mi[1]>=0;
for(int i=m+1;i<=n;i++) {
int p=lower_bound(b+1,b+1+m,h-a[i-m])-b;
if(p<=m) update(1,1,m,p,m,-1);
p=lower_bound(b+1,b+1+m,h-a[i])-b;
if(p<=m) update(1,1,m,p,m,1);
ans+=mi[1]>=0;
}
printf("%d",ans); return 0;
}

浙公网安备 33010602011771号