ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

hall 定理 & loj#6062. 「2017 山东一轮集训 Day2」Pair

2022-08-05 16:03:03  阅读:150  来源: 互联网

标签:le cur loj sum Day2 mid int ch 6062


hall 定理:对于任意二分图的一部的子集 \(S\),这些点在另一部所连的点集并为 \(S'\),若有 \(|S|\le |S'|\),那么该二分图有完美匹配。

证明的话考虑归纳喽,对于一个新点,给它分配一个,那么剩下的就是 \(n-1\) 的情况了。

图论的知识要补了。。。。

https://loj.ac/p/6062

回到这题。

考虑先对 \(b\) 降序排,那么对于 \(a\) 能够匹配的 \(b\) 一定是一段前缀,记 \(v_i\) 为 \(a_i\) 能匹配 \(b\) 的 \([1,v_i]\)。

考虑钦定 \([1,i]\) 为子集并,那么显然只能取 \(v_i\) 在 \([1,i]\) 内的,那么需要满足 \(\sum [v_i\le i]\le i\)。但是有时候不一定恰好钦定就有。考虑对答案有无影响。

即 \(s\le i\),显然 \(s\le i+1\),所以对答案并没有影响。

然后就是 DS 憨憨题了。

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
int rd() {
	int sum=0,f=1; char ch=getchar();
	while(ch>'9'||ch<'0') {
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0') {
		sum=sum*10+ch-'0'; ch=getchar();
	}
	return sum*f;
}
const int N=(int)(1.5e+5);
int n,m,h,v[N],a[N],b[N];

bool cmp(const int &x,const int &y) {
	return x>y;
}

int fd(int x) {
	int l=1,r=m,res=0;
	while(l<=r) {
		int mid=(l+r)>>1;
		if(b[mid]>=x) res=mid,l=mid+1;
		else r=mid-1;
	}
	return res;
}

namespace BIT {
	#define ls (cur<<1)
	#define rs (ls|1)
	int mx[N<<2],tag[N<<2];
	void push_up(int cur) {
		mx[cur]=max(mx[ls],mx[rs]);
	}
	void push_down(int cur) {
		if(!tag[cur]) return ;
		tag[ls]+=tag[cur]; tag[rs]+=tag[cur];
		mx[ls]+=tag[cur]; mx[rs]+=tag[cur];
		tag[cur]=0; 
	}
	void build(int cur,int l,int r) {
		tag[cur]=0;
		if(l==r) {
			mx[cur]=-l; return ;
		}
		int mid=(l+r)>>1;
		build(ls,l,mid); build(rs,mid+1,r);
		push_up(cur);
	}
	void upt(int cur,int l,int r,int cl,int cr,int v) {
		if(cl<=l&&r<=cr) {
			mx[cur]+=v; tag[cur]+=v; return ;
		}
		int mid=(l+r)>>1;
		push_down(cur);
		if(cl<=mid) upt(ls,l,mid,cl,cr,v);
		if(cr>mid) upt(rs,mid+1,r,cl,cr,v);
		push_up(cur);
	}
}
using namespace BIT;
signed 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,cmp);
	for(int i=1;i<=n;i++) {
		v[i]=fd(h-a[i]);
	}
	build(1,0,m);
	int ans=0;
	for(int i=1;i<=n;i++) {
		upt(1,0,m,v[i],m,1);
		if(i>=m) {
			int qwq=mx[1];
			if(qwq<=0) ++ans;
			upt(1,0,m,v[i-m+1],m,-1);
		}
	}
	printf("%d",ans);
	return 0;
} 

标签:le,cur,loj,sum,Day2,mid,int,ch,6062
来源: https://www.cnblogs.com/xugangfan/p/16554636.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有