题目描述

给出两个长度分别为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. python运算符及优先级顺序

    python语言是一门脚本语言,支持面向对象.面向过程编程,兼具编译性和解释性的动态语言,整理出学习过程中一些基本Python运算符和运算符的优先级顺序. 一.算术运算符 运算符 描述 + 加 - 两 ...

  2. mongo数据库相关目录

    mongodb的docker化安装 mongodb的windows系统下安装 grafana使用Prometheus数据源监控mongo数据库 mongodb副本集的docker化安装 mongodb ...

  3. laravel构造函数跳转失败

    <?php namespace App\Http\Controllers\Admin; use Illuminate\Http\Request; use App\Http\Requests;us ...

  4. IO复用——poll系统调用

    1.poll函数 #include<poll.h> int poll(struct pollfd* fds, nfds_t ndfs, int timeout) poll函数在一定的时间内 ...

  5. 单调队列优化dp

    洛谷p3800(单调队列优化DP) 题目背景 据说在红雾异变时,博丽灵梦单身前往红魔馆,用十分强硬的手段将事件解决了. 然而当时灵梦在Power达到MAX之前,不具有“上线收点”的能力,所以她想要知道 ...

  6. 1698-Just a Hook 线段树(区间替换)

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  7. cloudera manager服务迁移(scm数据库在postgresql上,其他amon,rman,oozie,metastore等在mysql上)

    公司线上大数据集群,之前用的是公有云主机,现在换成了自己idc机房机器,需要服务迁移,已下为测试: 1.备份原postgresql数据库: pg_dump -U scm scm > scm.sq ...

  8. sql插入查询出的数据,主键递增

    INSERT INTO C_DPRECORD SELECT (SEQ_C_DPRECORD.NEXTVAL ) AS ID, DEV_ID, DEV_CHNNUM, DEV_NAME, DEV_CHN ...

  9. Java集合类面试题

    java.util包中包含了一系列重要的集合类,而对于集合类,主要需要掌握的就是它的内部结构,以及遍历集合的迭代模式. 1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最 ...

  10. nginx location优先级

    目录 1. 配置语法 2. 配置实例 3. 总结: 网上查了下location的优先级规则,但是很多资料都说的模棱两可,自己动手实地配置了下,下面总结如下. 1. 配置语法 1> 精确匹配 lo ...