【bzoj2384】[Ceoi2011]Match 特殊匹配条件的KMP+树状数组
题目描述
给出两个长度分别为n、m的序列A、B,求出B的所有长度为n的连续子序列(子串),满足:序列中第i小的数在序列的Ai位置。
输入
第一行包含两个整数n, m (2≤n≤m≤1000000)。
第二行包含n个整数si,构成1,2,…,n的排列,1≤si≤n且si≠sj。
第三行包含m个整数hi,表示建筑的高度(1≤hi≤109,1≤i≤m),所有的hi均不相同。
每一行的整数之间用单个空格隔开。
输出
第一行包含1个整数k ,表示匹配的序列数目。
第二行包含k个整数,分别为在正确匹配的每个序列中与标志编号1 的条纹相对应的第1 栋建筑的编号。这些数字按升序排列,用空格隔开。如果k=0 ,第二行为空行。
样例输入
5 10
2 1 5 3 4
5 6 3 8 12 7 1 10 11 9
样例输出
2
2 6
题解
特殊匹配条件的KMP+树状数组
考虑:序列满足条件可以由 每个数前面比它小的数的个数 判定。
于是我们可以先预处理出每个数前面比它小的数应该有多少个。
然后如果暴力匹配的话肯定会TLE,于是想到KMP算法。
所以需要先求出next数组。
考虑KMP求next数组的过程:当满足条件时从前一个递推到后一个。那么可以使用树状数组维护比一个数小的数的个数,当当前小于该数的数的个数不等于应有的个数时就减少长度,并暴力将减掉的数从树状数组中删除。
由于每次next减少对应的是前面的next的增加,而next每次只增加1,因此对于每个字符的均摊时间复杂度是$O(\log m)$的。
然后求出next数组后就是匹配的过程,和求next类似,需要离散化。
因此总的时间复杂度为$O((n+m)\log m)$。貌似本题还有线性做法,然而不会= =
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 1000010
int m , a[N] , s[N] , v[N] , h[N] , t[N] , next[N] , f[N] , sta[N] , tot;
inline void add(int x , int a)
{
int i;
for(i = x ; i <= m ; i += i & -i) f[i] += a;
}
inline int query(int x)
{
int i , ans = 0;
for(i = x ; i ; i -= i & -i) ans += f[i];
return ans;
}
int main()
{
int n , i , j , p = 0;
scanf("%d%d" , &n , &m);
for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i]) , s[a[i]] = i;
for(i = 1 ; i <= n ; i ++ ) v[i] = query(s[i]) , add(s[i] , 1);
for(i = 1 ; i <= m ; i ++ ) scanf("%d" , &h[i]) , t[i] = h[i];
memset(f , 0 , sizeof(f));
for(i = 2 ; i <= n ; i ++ )
{
while(query(s[i]) != v[p + 1])
{
for(j = i - p ; j < i - next[p] ; j ++ ) add(s[j] , -1);
p = next[p];
}
next[i] = ++p , add(s[i] , 1);
}
sort(t + 1 , t + m + 1);
memset(f , 0 , sizeof(f));
p = 0;
for(i = 1 ; i <= m ; i ++ )
{
h[i] = lower_bound(t + 1 , t + m + 1 , h[i]) - t;
while(p == n || query(h[i]) != v[p + 1])
{
for(j = i - p ; j < i - next[p] ; j ++ ) add(h[j] , -1);
p = next[p];
}
p ++ , add(h[i] , 1);
if(p == n) sta[++tot] = i - n + 1;
}
printf("%d\n" , tot);
for(i = 1 ; i < tot ; i ++ ) printf("%d " , sta[i]);
if(tot) printf("%d" , sta[tot]);
return 0;
}
【bzoj2384】[Ceoi2011]Match 特殊匹配条件的KMP+树状数组的更多相关文章
- luoguP4696 [CEOI2011]Matching KMP+树状数组
可以非常轻易的将题意转化为有多少子串满足排名相同 注意到$KMP$算法只会在当前字符串的某尾添加和删除字符 因此,如果添加和删除后面的字符对于前面的字符没有影响时,我们可以用$KMP$来模糊匹配 对于 ...
- 【POJ 3167】Cow Patterns (KMP+树状数组)
Cow Patterns Description A particular subgroup of K (1 <= K <= 25,000) of Farmer John's cows l ...
- 【未完】训练赛20190304:KMP+树状数组+线段树+优先队列
头炸了啊,只做出L题,前两天刚看的Shawn zhou的博客学习的,幸亏看了啊,否则就爆零了,发现题目都是经典题,线段树,KMP,我都没看过,最近又在复习考研,真后悔大一大二没好好学习啊,得抽时间好好 ...
- 【poj 3167】Cow Patterns(字符串--KMP匹配+数据结构--树状数组)
题意:给2个数字序列 a 和 b ,问按从小到达排序后,a中的哪些子串与b的名次匹配. a 的长度 N≤100,000,b的长度 M≤25,000,数字的大小 K≤25. 解法:[思考]1.X 暴力. ...
- [bzoj1892][bzoj2384][bzoj1461][Ceoi2011]Match/字符串的匹配_KMP_树状数组
2384: [Ceoi2011]Match 1892: Match 1461: 字符串的匹配 题目大意: 数据范围: 题解: 很巧妙的一道题呀. 需要对$KMP$算法有很深的理解才行. 首先我们需要发 ...
- 【bzoj4641】基因改造 特殊匹配条件的KMP
题目描述 如果两个长度相等的字符串,如果存在一种字符的一一映射,使得第一个字符串的所有字符经过映射后与第二个字符串相同,那么就称它们“匹配”.现在给出两个串,求第一个字符串所有长度等于第二个字符串的长 ...
- bzoj1264 [AHOI2006]基因匹配Match 树状数组+lcs
1264: [AHOI2006]基因匹配Match Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1255 Solved: 835[Submit][ ...
- 【LOJ#2507】[CEOI2011]Matching(KMP,树状数组)
[LOJ#2507][CEOI2011]Matching(KMP,树状数组) 题面 LOJ 题解 发现要做的是排名串的匹配. 然后我们考虑把它转成这个位置之前有多少个数小于当前这个数,这样子只要每个位 ...
- bzoj 1264 [AHOI2006]基因匹配Match(DP+树状数组)
1264: [AHOI2006]基因匹配Match Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 793 Solved: 503[Submit][S ...
随机推荐
- 汇编:采用址表的方法编写程序实现C程序的switch功能
//待实现的C程序 1 void main() { ; -) { : printf("excellence"); break; : printf("good") ...
- 主流浏览器内核,以及CSS3前缀识别码
现在国内常见的浏览器有:IE.Firefox.QQ浏览器.Safari.Opera.Google Chrome.百度浏览器.搜狗浏览器.猎豹浏览器.360浏览器.UC浏览器.遨游浏览器.世界之窗浏览器 ...
- Spark 推送数据至 elasticsearch
1.工程依赖 <properties> <spark_version>2.3.1</spark_version> <!-- elasticsearch--&g ...
- oracle监听配置
在listener.ora文件中指定监听的实例名和修改ip地址: 查看实例名:[localhost$] echo $ORACLE_SID LISTENER = (DESCRIPTION_LIST = ...
- Go语言的标准net库使用
Go语言的标准net库使用 与大多数语言一样,Go的标准库是很全的,因为Go的出现本来就是为了网络通信的高并发实现,所以其相关的网络库封装得很简洁,也更加的易读.这里对使用到的api进行记录. net ...
- java 解析xml 多命名空间问题
先贴段有命名空间的xml吧.. <feed xmlns:im="http://itunes.apple.com/rss" xmlns="http://www.w3. ...
- Hadoop学习(四) FileSystem Shell命令详解
FileSystem Shell中大多数命令都和unix命令相同,只是两者之间的解释不同,如果你对unix命令有基本的了解,那么对于FileSystem Shell的命令,你将会感到很亲切. appe ...
- C#的特性Attribute
一.什么是特性 特性是用于在运行时传递程序中各种元素(比如类.方法.结构.枚举.组件等)的行为信息的声明性标签,这个标签可以有多个.您可以通过使用特性向程序添加声明性信息.一个声明性标签是通过放置在它 ...
- 【转】Ubuntu 14.04下Django+MySQL安装部署全过程
一.简要步骤.(阿里云Ubuntu14.04) Python安装 Django Mysql的安装与配置 记录一下我的部署过程,也方便一些有需要的童鞋,大神勿喷~ 二.Python的安装 由于博主使用的 ...
- mongodb 安装使用遇到的问题记录
mongodb 常用命令: https://www.mongodb.org/downloads 官网64位下载链接 https://fastdl.mongodb.org/linux/mongodb-l ...