LOJ #6062. 「2017 山东一轮集训 Day2」Pair
这是Lowest JN dalao昨天上课讲的一道神题其实是水题啦
题意很简单,我们也很容易建模转化出一个奇怪的东西
首先我们对b进行sort,然后我们就可以通过二分来判断出这个数可以和哪些数配对
然后我们稍微想一下就可以知道:每一段区间都是b数组后缀的形式
证明很简单,如果假设当前的数与第\(i\)位上的\(b_i\)不匹配,那么对于比\(b_i\)更小的\(b_{i-1}\)肯定是无法匹配的
然后我们可以转化为一个类似于二分图的完美匹配的问题,只不过其中匹配的数如上面所言是后缀的形式
然后我们可以套一个叫霍尔定理的东西,证明自看
然后我们发现对于所有的\(b_i(1\le i\le m)\),都需要有至少i根线段包含了它
更直接的,我们令一个统计数组\(c\),开始时\(c_i\)都等于\(-i\),这样每次只需要给一个后缀加1即可
然后查询是否可以实现只需要看一下最小值是否>=0即可
然后直接做是肯定T的,然后我们发现我们需要完成的任务:
- 区间加
- 区间减(在抵消之前的操作是会用到)
- 区间最值查询
这不就是线段树随便维护一下的东西吗。
CODE
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=150005;
int a[N],b[N],c[N],r[N],n,m,ans,h;
struct segtree
{
int s,add;
}tree[N<<2];
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch=tc();
while (ch<'0'||ch>'9') ch=tc();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
inline int find(int x)
{
int l=1,r=m,res=m+1;
while (l<=r)
{
int mid=l+r>>1;
if (b[mid]>=x) res=mid,r=mid-1; else l=mid+1;
}
return res;
}
inline int min(int a,int b)
{
return a<b?a:b;
}
inline void up(int rt)
{
tree[rt].s=min(tree[rt<<1].s,tree[rt<<1|1].s);
}
inline void down(int rt)
{
if (tree[rt].add)
{
tree[rt<<1].add+=tree[rt].add; tree[rt<<1|1].add+=tree[rt].add;
tree[rt<<1].s+=tree[rt].add; tree[rt<<1|1].s+=tree[rt].add;
tree[rt].add=0;
}
}
inline void build(int rt,int l,int r)
{
if (l==r)
{
tree[rt].s=c[l];
return;
}
int mid=l+r>>1;
build(rt<<1,l,mid); build(rt<<1|1,mid+1,r);
up(rt);
}
inline void modify(int rt,int l,int r,int beg,int end,int k)
{
if (l>=beg&&r<=end)
{
tree[rt].add+=k; tree[rt].s+=k;
return;
}
int mid=l+r>>1;
down(rt);
if (beg<=mid) modify(rt<<1,l,mid,beg,end,k);
if (end>mid) modify(rt<<1|1,mid+1,r,beg,end,k);
up(rt);
}
inline int query(int rt,int l,int r,int beg,int end)
{
if (l>=beg&&r<=end) return tree[rt].s;
int mid=l+r>>1,res=1e9;
down(rt);
if (beg<=mid) res=min(res,query(rt<<1,l,mid,beg,end));
if (end>mid) res=min(res,query(rt<<1|1,mid+1,r,beg,end));
up(rt); return res;
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
register int i; read(n); read(m); read(h);
for (i=1;i<=m;++i)
read(b[i]),c[i]=-i; sort(b+1,b+m+1);
for (i=1;i<=n;++i)
read(a[i]);
build(1,1,m);
for (i=1;i<=m;++i)
{
r[i]=find(h-a[i]);
if (r[i]<=m) modify(1,1,m,r[i],m,1);
}
if (query(1,1,m,1,m)>=0) ++ans;
for (i=m+1;i<=n;++i)
{
r[i]=find(h-a[i]);
if (r[i-m]<=m) modify(1,1,m,r[i-m],m,-1);
if (r[i]<=m) modify(1,1,m,r[i],m,1);
if (query(1,1,m,1,m)>=0) ++ans;
}
printf("%d",ans);
return 0;
}
LOJ #6062. 「2017 山东一轮集训 Day2」Pair的更多相关文章
- loj#6062. 「2017 山东一轮集训 Day2」Pair hall定理+线段树
题意:给出一个长度为 n的数列 a和一个长度为 m 的数列 b,求 a有多少个长度为 m的连续子数列能与 b匹配.两个数列可以匹配,当且仅当存在一种方案,使两个数列中的数可以两两配对,两个数可以配对当 ...
- ACM-ICPC 2017 西安赛区现场赛 K. LOVER II && LibreOJ#6062. 「2017 山东一轮集训 Day2」Pair(线段树)
题目链接:西安:https://nanti.jisuanke.com/t/20759 (计蒜客的数据应该有误,题目和 LOJ 的大同小异,题解以 LOJ 为准) LOJ:https://l ...
- 【LOJ6062】「2017 山东一轮集训 Day2」Pair(线段树套路题)
点此看题面 大致题意: 给出一个长度为\(n\)的数列\(a\)和一个长度为\(m\)的数列\(b\),求\(a\)有多少个长度为\(m\)的子串与\(b\)匹配.数列匹配指存在一种方案使两个数列中的 ...
- LOJ6062「2017 山东一轮集训 Day2」Pair(Hall定理,线段树)
题面 给出一个长度为 n n n 的数列 { a i } \{a_i\} {ai} 和一个长度为 m m m 的数列 { b i } \{b_i\} {bi},求 { a i } \{a_i\} ...
- Loj #6069. 「2017 山东一轮集训 Day4」塔
Loj #6069. 「2017 山东一轮集训 Day4」塔 题目描述 现在有一条 $ [1, l] $ 的数轴,要在上面造 $ n $ 座塔,每座塔的坐标要两两不同,且为整点. 塔有编号,且每座塔都 ...
- Loj #6073.「2017 山东一轮集训 Day5」距离
Loj #6073.「2017 山东一轮集训 Day5」距离 Description 给定一棵 \(n\) 个点的边带权的树,以及一个排列$ p\(,有\)q $个询问,给定点 \(u, v, k\) ...
- Loj 6068. 「2017 山东一轮集训 Day4」棋盘
Loj 6068. 「2017 山东一轮集训 Day4」棋盘 题目描述 给定一个 $ n \times n $ 的棋盘,棋盘上每个位置要么为空要么为障碍.定义棋盘上两个位置 $ (x, y),(u, ...
- LOJ #6074. 「2017 山东一轮集训 Day6」子序列
#6074. 「2017 山东一轮集训 Day6」子序列 链接 分析: 首先设f[i][j]为到第i个点,结尾字符是j的方案数,这个j一定是从i往前走,第一个出现的j,因为这个j可以代替掉前面所有j. ...
- loj #6077. 「2017 山东一轮集训 Day7」逆序对
#6077. 「2017 山东一轮集训 Day7」逆序对 题目描述 给定 n,k n, kn,k,请求出长度为 n nn 的逆序对数恰好为 k kk 的排列的个数.答案对 109+7 10 ^ 9 ...
随机推荐
- 安卓开发_浅谈WebView(转)
,有一个功能需要在APP中调用网站 百度了一下,发现需要用WebView来实现 实现方法很容易,我就不在这里写一遍了 ,直接转一下我学习的内容吧 原创作品,允许转载,转载时请务必以超链接形式标明文章 ...
- Java集合之TreeMap源码分析
一.概述 TreeMap是基于红黑树实现的.由于TreeMap实现了java.util.sortMap接口,集合中的映射关系是具有一定顺序的,该映射根据其键的自然顺序进行排序或者根据创建映射时提供的C ...
- 使用wxpy自动发送微信消息
思路整理:1.进入心灵鸡汤网页,使用python获取心灵鸡汤内容 2.登陆微信,找到需要发送的朋友 3.发送获取的内容 1.获取心灵鸡汤的内容 如下图,获取第一条鸡汤 实现如下: 2.登陆微信,搜索朋 ...
- python第五十四天--第十周作业
SELECT版FTP:使用SELECT或SELECTORS模块实现并发简单版FTP允许多用户并发上传下载文件 必须使用select or selectors模块支持多并发,禁止使用多线程或多进程 RE ...
- python第五十三天--进程,协程.select.异步I/O...
进程: #!usr/bin/env python #-*-coding:utf-8-*- # Author calmyan import multiprocessing,threading,time ...
- 开发测试技巧|辅助开发调试:goolge浏览器利用F12在控制台输入脚本实现表单自动填充
一个开发测试技巧的指引和截图,利用google浏览器的F12调试和Console执行,注入JavaScript脚本实现表单的自动填充和测试. 原文链接: http://www.lookdaima.co ...
- 通过explain分析低效的SQL执行计划
之前我们讲过如何开启慢查询日志,这个日志的最大作用就是我们通过设定超时阈值,在执行SQL语句中的消耗时间大于这个阈值,将会被记录到慢查询日志里面.DBA通过这个慢查询日志定位到执行缓慢的sql语句,以 ...
- rls与rlsd
服务器端的程序一般有如下几个过程,首先是bind,然后再是listen,最后是accept.再往后就是客户端与服务器连接后的各种操作了. 相比之下,客户端的程序就比较简单了,只需先获得sock_id, ...
- Android Studio入门问题汇总
1.如何设置 AS 中的字体大小 2.如何切换 AS 的皮肤颜色,默认为黑色,修改为白色,改为 default 3.首次安装 Android Studio并打开时,如果创建了一个新工程并将工程保存在另 ...
- arcgis如何求两个栅格数据集的差集
栅格数据集没有擦除功能,现在有栅格A和栅格B,怎么求两个栅格的差集C 具体步骤如下: 1.首先利用栅格计算器,把栅格B中的value全部赋值为0 输入语句:"栅格B" * 0 2 ...