loj#6062. 「2017 山东一轮集训 Day2」Pair

首先这题对于 a[l,l+m1] 能够成功匹配,当且仅当去连边,然后能形成完美匹配。

但是边数可能到 m2 的级别,所以跑不了 dinic,但我们只需要判断是否有。

于是,考虑 hall 定理,即对于二分图一部的子集 S,每个点在另一部连得边的并集 S,有 |S||S|,则该二分图有完美匹配。

考虑线段树维护前缀 couldii

[1,r],rcouldr

[l,r],l1couldl1,rcouldr

r(l1)couldrcouldl1

couldii0

对于一部的点集动态,就不能先 build 了。

实际上 b 升序/顺序没有影响。处理麻烦或简单而已。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<code-pre class="code-pre" id="pre-mZtMae"><code-line class="line-numbers-rows"></code-line>#include <cstdio>
<code-line class="line-numbers-rows"></code-line>#include <algorithm>
<code-line class="line-numbers-rows"></code-line>#include <iostream>
<code-line class="line-numbers-rows"></code-line>#include <cstring>
<code-line class="line-numbers-rows"></code-line>#include <vector>
<code-line class="line-numbers-rows"></code-line>#include <cmath>
<code-line class="line-numbers-rows"></code-line>#include <queue>
<code-line class="line-numbers-rows"></code-line>#include <map>
<code-line class="line-numbers-rows"></code-line>
<code-line class="line-numbers-rows"></code-line>#define ll long long
<code-line class="line-numbers-rows"></code-line>
<code-line class="line-numbers-rows"></code-line>using namespace std;
<code-line class="line-numbers-rows"></code-line>int rd() {
<code-line class="line-numbers-rows"></code-line>   int f=1,sum=0; char ch=getchar();
<code-line class="line-numbers-rows"></code-line>   while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
<code-line class="line-numbers-rows"></code-line>   while(isdigit(ch)) {sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
<code-line class="line-numbers-rows"></code-line>   return sum*f;
<code-line class="line-numbers-rows"></code-line>}
<code-line class="line-numbers-rows"></code-line>ll lrd() {
<code-line class="line-numbers-rows"></code-line>   ll f=1,sum=0; char ch=getchar();
<code-line class="line-numbers-rows"></code-line>   while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
<code-line class="line-numbers-rows"></code-line>   while(isdigit(ch)) {sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
<code-line class="line-numbers-rows"></code-line>   return sum*f;
<code-line class="line-numbers-rows"></code-line>}
<code-line class="line-numbers-rows"></code-line>#define ls (cur<<1)
<code-line class="line-numbers-rows"></code-line>#define rs (ls|1)
<code-line class="line-numbers-rows"></code-line>
<code-line class="line-numbers-rows"></code-line>const int N=(int)(1.5e5+5);
<code-line class="line-numbers-rows"></code-line>int mi[N<<2],tag[N<<2];
<code-line class="line-numbers-rows"></code-line>int n,m,h,a[N],b[N];
<code-line class="line-numbers-rows"></code-line>
<code-line class="line-numbers-rows"></code-line>void push_up(int cur) {
<code-line class="line-numbers-rows"></code-line>   mi[cur]=min(mi[ls],mi[rs]);
<code-line class="line-numbers-rows"></code-line>}
<code-line class="line-numbers-rows"></code-line>
<code-line class="line-numbers-rows"></code-line>void push_down(int cur) {
<code-line class="line-numbers-rows"></code-line>   if(!tag[cur]) return ;
<code-line class="line-numbers-rows"></code-line>   tag[ls]+=tag[cur]; tag[rs]+=tag[cur];
<code-line class="line-numbers-rows"></code-line>   mi[ls]+=tag[cur]; mi[rs]+=tag[cur];
<code-line class="line-numbers-rows"></code-line>   tag[cur]=0;
<code-line class="line-numbers-rows"></code-line>}
<code-line class="line-numbers-rows"></code-line>
<code-line class="line-numbers-rows"></code-line>void build(int cur,int l,int r) {
<code-line class="line-numbers-rows"></code-line>   mi[cur]=0x3f3f3f3f;
<code-line class="line-numbers-rows"></code-line>   if(l==r) return mi[cur]=-l,void();
<code-line class="line-numbers-rows"></code-line>   int mid=(l+r)>>1;
<code-line class="line-numbers-rows"></code-line>   build(ls,l,mid); build(rs,mid+1,r);
<code-line class="line-numbers-rows"></code-line>   push_up(cur);
<code-line class="line-numbers-rows"></code-line>}
<code-line class="line-numbers-rows"></code-line>
<code-line class="line-numbers-rows"></code-line>void update(int cur,int l,int r,int cl,int cr,int v) {
<code-line class="line-numbers-rows"></code-line>   if(cl<=l&&r<=cr) {
<code-line class="line-numbers-rows"></code-line>       tag[cur]+=v; mi[cur]+=v; return ;
<code-line class="line-numbers-rows"></code-line>   }
<code-line class="line-numbers-rows"></code-line>   push_down(cur);
<code-line class="line-numbers-rows"></code-line>   int mid=(l+r)>>1;
<code-line class="line-numbers-rows"></code-line>   if(cl<=mid) update(ls,l,mid,cl,cr,v);
<code-line class="line-numbers-rows"></code-line>   if(cr>mid) update(rs,mid+1,r,cl,cr,v);
<code-line class="line-numbers-rows"></code-line>   push_up(cur);
<code-line class="line-numbers-rows"></code-line>}
<code-line class="line-numbers-rows"></code-line>
<code-line class="line-numbers-rows"></code-line>int main() {
<code-line class="line-numbers-rows"></code-line>   n=rd(); m=rd(); h=rd();
<code-line class="line-numbers-rows"></code-line>   for(int i=1;i<=m;i++) b[i]=rd();
<code-line class="line-numbers-rows"></code-line>   for(int i=1;i<=n;i++) a[i]=rd();
<code-line class="line-numbers-rows"></code-line>   sort(b+1,b+1+m);
<code-line class="line-numbers-rows"></code-line>   build(1,1,m);
<code-line class="line-numbers-rows"></code-line>   int ans=0; // a[i]+b[i]>=h a[i]-h>=b[i]
<code-line class="line-numbers-rows"></code-line>   for(int i=1;i<=m;i++) {
<code-line class="line-numbers-rows"></code-line>       int p=lower_bound(b+1,b+1+m,h-a[i])-b;
<code-line class="line-numbers-rows"></code-line>       if(p<=m) update(1,1,m,p,m,1);
<code-line class="line-numbers-rows"></code-line>   }
<code-line class="line-numbers-rows"></code-line>   ans+=mi[1]>=0;
<code-line class="line-numbers-rows"></code-line>   for(int i=m+1;i<=n;i++) {
<code-line class="line-numbers-rows"></code-line>       int p=lower_bound(b+1,b+1+m,h-a[i-m])-b;
<code-line class="line-numbers-rows"></code-line>       if(p<=m) update(1,1,m,p,m,-1);
<code-line class="line-numbers-rows"></code-line>       p=lower_bound(b+1,b+1+m,h-a[i])-b;
<code-line class="line-numbers-rows"></code-line>       if(p<=m) update(1,1,m,p,m,1);
<code-line class="line-numbers-rows"></code-line>       ans+=mi[1]>=0;
<code-line class="line-numbers-rows"></code-line>   }
<code-line class="line-numbers-rows"></code-line>   printf("%d",ans); return 0;
<code-line class="line-numbers-rows"></code-line>}
</code-pre>

  


__EOF__

本文作者F x o r G
本文链接https://www.cnblogs.com/xugangfan/p/15210578.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   FxorG  阅读(74)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示