题目描述

给出两个长度分别为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+树状数组的更多相关文章

  1. luoguP4696 [CEOI2011]Matching KMP+树状数组

    可以非常轻易的将题意转化为有多少子串满足排名相同 注意到$KMP$算法只会在当前字符串的某尾添加和删除字符 因此,如果添加和删除后面的字符对于前面的字符没有影响时,我们可以用$KMP$来模糊匹配 对于 ...

  2. 【POJ 3167】Cow Patterns (KMP+树状数组)

    Cow Patterns Description A particular subgroup of K (1 <= K <= 25,000) of Farmer John's cows l ...

  3. 【未完】训练赛20190304:KMP+树状数组+线段树+优先队列

    头炸了啊,只做出L题,前两天刚看的Shawn zhou的博客学习的,幸亏看了啊,否则就爆零了,发现题目都是经典题,线段树,KMP,我都没看过,最近又在复习考研,真后悔大一大二没好好学习啊,得抽时间好好 ...

  4. 【poj 3167】Cow Patterns(字符串--KMP匹配+数据结构--树状数组)

    题意:给2个数字序列 a 和 b ,问按从小到达排序后,a中的哪些子串与b的名次匹配. a 的长度 N≤100,000,b的长度 M≤25,000,数字的大小 K≤25. 解法:[思考]1.X 暴力. ...

  5. [bzoj1892][bzoj2384][bzoj1461][Ceoi2011]Match/字符串的匹配_KMP_树状数组

    2384: [Ceoi2011]Match 1892: Match 1461: 字符串的匹配 题目大意: 数据范围: 题解: 很巧妙的一道题呀. 需要对$KMP$算法有很深的理解才行. 首先我们需要发 ...

  6. 【bzoj4641】基因改造 特殊匹配条件的KMP

    题目描述 如果两个长度相等的字符串,如果存在一种字符的一一映射,使得第一个字符串的所有字符经过映射后与第二个字符串相同,那么就称它们“匹配”.现在给出两个串,求第一个字符串所有长度等于第二个字符串的长 ...

  7. bzoj1264 [AHOI2006]基因匹配Match 树状数组+lcs

    1264: [AHOI2006]基因匹配Match Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1255  Solved: 835[Submit][ ...

  8. 【LOJ#2507】[CEOI2011]Matching(KMP,树状数组)

    [LOJ#2507][CEOI2011]Matching(KMP,树状数组) 题面 LOJ 题解 发现要做的是排名串的匹配. 然后我们考虑把它转成这个位置之前有多少个数小于当前这个数,这样子只要每个位 ...

  9. bzoj 1264 [AHOI2006]基因匹配Match(DP+树状数组)

    1264: [AHOI2006]基因匹配Match Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 793  Solved: 503[Submit][S ...

随机推荐

  1. 编译安装开源免费中文分词scws

    一.SCWS了解一下: SCWS 是 Simple Chinese Word Segmentation 的首字母缩写(即:简易中文分词系统). 这是一套基于词频词典的机械式中文分词引擎,它能将一整段的 ...

  2. Laravel-admin 当使用Form组件hasMany的时候 进行编辑出现错误 foreach错误的时候解决方案

    我的关联关系原名是 goodImage 修改成 image 之后解决问题 分析得出应该是  laravel会将goodImage 转成 good_image字段  这样就foreach会报错  所以出 ...

  3. hive 学习系列三(表格的创建create-table)

    表格创建: 语法 第一种建表的形式: 说明: temporary 临时表,在当前回话内,这张表有效,当回话结束,可以理解为程序结束,则程序终止. external 外部表, hdfs 上的表的文件,并 ...

  4. 【Leetcode】Jewels and Stones

    Jewels and Stones Description You're given strings J representing the types of stones that are jewel ...

  5. COURSES POJ1469(模板)

    Description Consider a group of N students and P courses. Each student visits zero, one or more than ...

  6. Python标准库--inspect

    inspect模块是针对模块,类,方法,功能等对象提供些有用的方法.例如可以帮助我们检查类的内容,检查方法的代码,提取和格式化方法的参数等. import inspect import os clas ...

  7. XML文件中关键字自动提示和不全配置

    一.获得mybatis-3-config.dtd.mybatis-3-mapper.dtd 这两个文件. 建立一个Maven的项目 在Pom.xml文件中的Mybatis jar包的下载设置(也可以从 ...

  8. 面试官常问的10个Linux问题

    1.如何暂停一个正在运行的进程,把其放在后台(不运行)? 为了停止正在运行的进程,让其再后台运行,我们可以使用组合键Ctrl+Z. 2.什么是安装Linux所需的最小分区数量,以及如何查看系统启动信息 ...

  9. 如何删除TFS项目

    TFS是先建集合,再在集合下面建项目.删除的时候,需要先删除项目,再删除集合,然后重新建.具体步骤如下: 1.删除项目        删除项目必须通过命令来进行删除,调用TFSDeleteProjec ...

  10. 手把手教你玩转CSS3 3D技术

    手把手教你玩转 CSS3 3D 技术   要玩转css3的3d,就必须了解几个词汇,便是透视(perspective).旋转(rotate)和移动(translate).透视即是以现实的视角来看屏幕上 ...