题面

给出一个长度为

n

n

n 的数列

{

a

i

}

\{a_i\}

{ai​} 和一个长度为

m

m

m 的数列

{

b

i

}

\{b_i\}

{bi​},求

{

a

i

}

\{a_i\}

{ai​} 有多少个长度为

m

m

m 的连续子数列能与

{

b

i

}

\{b_i\}

{bi​} 匹配。

两个数列可以匹配,当且仅当存在一种方案,使两个数列中的数可以两两配对,两个数可以配对当且仅当它们的和不小于

h

h

h。

1

m

n

150000.

1\leq m\leq n\leq 150000.

1≤m≤n≤150000.

题解

条件等价于子二分图存在完备匹配。

我们从数列

B

B

B 的角度考虑,根据 Hall 定理,要保证

B

B

B 的任意子集

S

S

S 满足

S

N

(

S

)

|S|\leq |N(S)|

∣S∣≤∣N(S)∣ ,

N

(

S

)

N(S)

N(S) 表示

S

S

S 中所有点的邻接点构成的集合。

然后,我们会发现连边具有单调性,

a

i

a_i

ai​ 可以和所有大于等于

h

a

i

h-a_i

h−ai​ 的

b

j

b_j

bj​ 连边。所以,我们把

B

B

B 从小到大排序,每个

a

i

a_i

ai​ 的邻接点集就是

B

B

B 的某段后缀。

这就意味着,对于

i

<

j

m

,

N

(

i

)

N

(

j

)

\forall i<j\leq m~,~N(i)\sube N(j)

∀i<j≤m , N(i)⊆N(j) ,即

i

i

i 的邻接点集一定是

j

j

j 的邻接点集的子集。很容易就能得到,如果

B

B

B 的某前缀

P

P

P 满足

P

N

(

P

)

|P|\leq|N(P)|

∣P∣≤∣N(P)∣ ,那么对于任意

S

B

,

S

=

P

S\sube B,|S|=|P|

S⊆B,∣S∣=∣P∣ ,也一定满足

S

N

(

S

)

|S|\leq|N(S)|

∣S∣≤∣N(S)∣ 。

于是,我们需要考虑的子集从

2

m

1

2^m-1

2m−1 个锐减至

m

m

m 个。而且,明显可以用线段树维护每个前缀的邻接点集大小,存在完备匹配的条件即

min

{

N

(

P

)

P

}

0

\min\{|N(P)|-|P|\}\geq 0

min{∣N(P)∣−∣P∣}≥0 。

时间复杂度

O

(

n

log

m

)

O(n\log m)

O(nlogm) 。

CODE

#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<bitset>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 150005
#define LL long long
#define DB double
#define ENDL putchar('\n')
#define lowbit(x) (-(x) & (x))
LL read() {
LL f=1,x=0;int s = getchar();
while(s < '0' || s > '9') {if(s<0)return -1;if(s=='-')f=-f;s=getchar();}
while(s >= '0' && s <= '9') {x = (x<<3) + (x<<1) + (s^48);s = getchar();}
return f * x;
}
void putpos(LL x) {if(!x)return ;putpos(x/10);putchar((x%10)^48);};
void putnum(LL x) {
if(!x) {putchar('0');return ;}
if(x<0) putchar('-'),x = -x;
return putpos(x);
}
void AIput(LL x,int c) {putnum(x);putchar(c);} int n,m,s,o,k;
int H;
int a[MAXN],b[MAXN],ad[MAXN];
int tre[MAXN<<2],lz[MAXN<<2],M;
void maketree(int n) {
M=1;while(M<n+2)M<<=1;
for(int i = 1;i <= n;i ++) {
tre[M+i] = -i;
}
for(int i = M-1;i > 0;i --) {
tre[i] = min(tre[i<<1],tre[i<<1|1]);
}return ;
}
void addtree(int l,int r,int y) {
if(l > r) return ;
for(int s=M+l-1,t=M+r+1;s || t;s >>= 1,t >>= 1) {
if(s<M) tre[s] = min(tre[s<<1],tre[s<<1|1]) + lz[s];
if(t<M) tre[t] = min(tre[t<<1],tre[t<<1|1]) + lz[t];
if((s>>1) ^ (t>>1)) {
if(!(s&1)) tre[s^1] += y,lz[s^1] += y;
if(t & 1) tre[t^1] += y,lz[t^1] += y;
}
}return ;
}
int main() {
n = read();m = read();H = read();
for(int i = 1;i <= m;i ++) {
b[i] = read();
}
for(int i = 1;i <= n;i ++) {
a[i] = read();
}
sort(b + 1,b + 1 + m);
maketree(m);
int ans = 0;
for(int i = 1;i <= n;i ++) {
ad[i] = lower_bound(b + 1,b + 1 + m,H-a[i]) - b;
addtree(ad[i],m,1);
if(i > m) addtree(ad[i-m],m,-1);
if(tre[1] >= 0) ans ++;
}
AIput(ans,'\n');
return 0;
}

LOJ6062「2017 山东一轮集训 Day2」Pair(Hall定理,线段树)的更多相关文章

  1. loj#6062. 「2017 山东一轮集训 Day2」Pair hall定理+线段树

    题意:给出一个长度为 n的数列 a和一个长度为 m 的数列 b,求 a有多少个长度为 m的连续子数列能与 b匹配.两个数列可以匹配,当且仅当存在一种方案,使两个数列中的数可以两两配对,两个数可以配对当 ...

  2. 【LOJ6062】「2017 山东一轮集训 Day2」Pair(线段树套路题)

    点此看题面 大致题意: 给出一个长度为\(n\)的数列\(a\)和一个长度为\(m\)的数列\(b\),求\(a\)有多少个长度为\(m\)的子串与\(b\)匹配.数列匹配指存在一种方案使两个数列中的 ...

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

    这是Lowest JN dalao昨天上课讲的一道神题其实是水题啦 题意很简单,我们也很容易建模转化出一个奇怪的东西 首先我们对b进行sort,然后我们就可以通过二分来判断出这个数可以和哪些数配对 然 ...

  4. ACM-ICPC 2017 西安赛区现场赛 K. LOVER II && LibreOJ#6062. 「2017 山东一轮集训 Day2」Pair(线段树)

    题目链接:西安:https://nanti.jisuanke.com/t/20759   (计蒜客的数据应该有误,题目和 LOJ 的大同小异,题解以 LOJ 为准)     LOJ:https://l ...

  5. Loj #6069. 「2017 山东一轮集训 Day4」塔

    Loj #6069. 「2017 山东一轮集训 Day4」塔 题目描述 现在有一条 $ [1, l] $ 的数轴,要在上面造 $ n $ 座塔,每座塔的坐标要两两不同,且为整点. 塔有编号,且每座塔都 ...

  6. Loj #6073.「2017 山东一轮集训 Day5」距离

    Loj #6073.「2017 山东一轮集训 Day5」距离 Description 给定一棵 \(n\) 个点的边带权的树,以及一个排列$ p\(,有\)q $个询问,给定点 \(u, v, k\) ...

  7. Loj 6068. 「2017 山东一轮集训 Day4」棋盘

    Loj 6068. 「2017 山东一轮集训 Day4」棋盘 题目描述 给定一个 $ n \times n $ 的棋盘,棋盘上每个位置要么为空要么为障碍.定义棋盘上两个位置 $ (x, y),(u, ...

  8. 「2017 山东一轮集训 Day5」苹果树

    「2017 山东一轮集训 Day5」苹果树 \(n\leq 40\) 折半搜索+矩阵树定理. 没有想到折半搜索. 首先我们先枚举\(k\)个好点,我们让它们一定没有用的.要满足这个条件就要使它只能和坏 ...

  9. 【LOJ#6066】「2017 山东一轮集训 Day3」第二题(哈希,二分)

    [LOJ#6066]「2017 山东一轮集训 Day3」第二题(哈希,二分) 题面 LOJ 题解 要哈希是很显然的,那么就考虑哈希什么... 要找一个东西可以表示一棵树,所以我们找到了括号序列. 那么 ...

随机推荐

  1. Linux系统安装ActiveMQ

    下载安装包 https://activemq.apache.org/components/classic/download/ 上传至服务器并解压 [root@localhost activemq]# ...

  2. JAVA 异常 基本知识

    异常 异常定义 异常是运行过程中出现的错误 人为错误:填写错误等 随机错误:网络中断.内存耗尽等 一个健壮的程序必须处理各种各样的错误 Java的异常是class Object Throwable E ...

  3. 皓远的第一次博客作业(pta题目集——1-3)

    题目集总结: 前言: 一. 知识点运用: ①    Java入门的基础语法(循环,判断,字符串,数组等等),Java的基础类运用,类与对象关系调用,类间关系(聚合). ②    引(类与对象): 对象 ...

  4. VR技术的应用领域有哪些?

    5G时代已经到来,新技术的商用不仅能够为用户带来更快的网络连接速度,那些依靠网速的提升,而得以更快发展的科技企业,也迎来了新的发展契机. 这其中,尤为值得关注的是VR领域. 谈起VR,这并不算一个陌生 ...

  5. cve_2019_0708_bluekeep漏洞

    一.环境说明 kali linux windows 7 sp1 二.cve_2019_0708_bluekeep漏洞利用 msf5 auxiliary(dos/windows/rdp/ms12_020 ...

  6. 更好的Android多线程下载框架

    /** * 作者:Pich * 原文链接:http://me.woblog.cn/ * QQ群:129961195 * Github:https://github.com/lifengsofts */ ...

  7. 全国土壤阳离子交换量CEC空间分布数据

    数据下载链接:百度云下载链接​ 土壤阳离子交换量,简称CEC,是指土壤胶体所能吸附各种阳离子的总量.土壤阳离子交换量 cation exchange capacity 即CEC 是指土壤胶体所能吸附各 ...

  8. 一文搞懂 Netty 发送数据全流程 | 你想知道的细节全在这里

    欢迎关注公众号:bin的技术小屋,如果大家在看文章的时候发现图片加载不了,可以到公众号查看原文 本系列Netty源码解析文章基于 4.1.56.Final版本 在<Netty如何高效接收网络数据 ...

  9. k8s+crio+podman搭建集群

    前言 在传统的k8s集群中,我们都是使用docker engine做为底层的容器管理软件的,而docker engine因为不是k8s亲生的解决方案,所以实际使用中会有更多的分层.之前我们也讲过,k8 ...

  10. 5-2 Nacos注册中心

    Nacos注册中心 什么Nacos Nacos是Spring Cloud Alibaba提供的一个软件 这个软件主要具有注册中心和配置中心的功能 我们先学习它注册中心的功能 微服务中所有项目都必须注册 ...