很久之前做的一题,忽然想起来,依然觉得思路巧妙。

//这道题,确实是一道好题。但如何应用KMP,确实大大超出了意料中。
//这道题匹配的是某元素在子串中的名次,也就是在子串中排第几小。我想了整整一天,才想到一个较好
//的方法来确定在子串中的位置,本来以为可以用这个来暴力枚举再加剪枝可以过,但没想到。。TLE //代码是转的,算法也是看过别人的才懂。
//好吧,看过别人的解题,写的代码不难,算法特别难想。首先统计在位置I的元素之前,比该元素小的个数
//以及和该元素相等的个数,这个我用暴力枚举来预处理,也有用树状数组的,但我看不懂。然后重新修改
//匹配的定义:假设前N-1个元素匹配,则第N个元素匹配的条件是该元素之前的(当然必须是在子串范围内)
//小于与等于该元素的个数都分别相等。我试图否定它,但总感觉是显而易见的,可我没想到。接下来就可以
//据此来求NEXT函数了。在求NEXT时,必须注意是要求N-1个元素中小于与等于N元素的个数分别相等。 //我想做一次事后诸葛亮(虽然本人不是什么牛人),总结一下:
//我觉得,以后遇到配匹模式串的题应该都可以用KMP来解题,真心觉得KMP是十分的一个算法。但在应用NEXT
//函数时,应适当改一下定义,怎么改呢?我认为,要求某位置的NEXT的值,应该首先满足的条件时,该位置
//之前的字符或数已匹配,所以,应当先假设前N个元素匹配,再给出N+1个元素匹配的条件,且应该是无须
//理会N+1之后的影响的。这样就可以进行KMP了。 #include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std; int n,k,s; struct TT
{
int len;
int num[];
int low[][],equ[][];
} t,p; void init(TT &tmp)
{
for(int i =;i<=tmp.len;i++)
{
for(int j = ;j<=s;j++)
{
tmp.low[i][j] = tmp.low[i-][j] + (tmp.num[i] < j ? : );
tmp.equ[i][j] = tmp.equ[i-][j] + (tmp.num[i] == j ? : );
}
}
} int fail[]; int check(TT &a,TT &b,int i,int j)
{
if(a.low[i][a.num[i]] - a.low[i - j][a.num[i]] == b.low[j][b.num[j]]
&& a.equ[i][a.num[i]] - a.equ[i - j][a.num[i]] == b.equ[j][b.num[j]])
return ;
return ;
} void get_fail()
{
fail[] = ;
int j = ;
for(int i = ;i<=k;i++)
{
if(j >= && !check(p,p,i,j+) )
j = fail[j];
if(check(p,p,i,j+)) j++;
fail[i] = j;
}
} vector <int> ans; void kmp()
{
ans.clear();
get_fail();
int j = ;
for(int i = ;i<=n;i++)
{
while(j >= && !check(t,p,i,j+)) j = fail[j];
if(check(t,p,i,j+)) j++; if(j == k)
{
ans.push_back(i-k+);
j = fail[j];
}
}
} int main()
{
while(~scanf("%d%d%d",&n,&k,&s))
{
for(int i = ;i<=n;i++)
scanf("%d",&t.num[i]);
for(int i = ;i<=k;i++)
scanf("%d",&p.num[i]);
t.len = n;
p.len = k;
init(t);
init(p);
kmp();
printf("%d\n",ans.size());
for(int i = ;i<ans.size();i++)
printf("%d\n",ans[i]);
}
return ;
}

HDU 3167 KMP的更多相关文章

  1. hdu 1686 KMP模板

    // hdu 1686 KMP模板 // 没啥好说的,KMP裸题,这里是MP模板 #include <cstdio> #include <iostream> #include ...

  2. Cyclic Nacklace HDU 3746 KMP 循环节

    Cyclic Nacklace HDU 3746 KMP 循环节 题意 给你一个字符串,然后在字符串的末尾添加最少的字符,使这个字符串经过首尾链接后是一个由循环节构成的环. 解题思路 next[len ...

  3. HDU 2087 (KMP不可重叠的匹配) 花布条

    题意: 用两个字符串分别表示布条和图案,问能从该布条上剪出多少这样的图案. 分析: 毫无疑问这也是用KMP匹配,关键是一次匹配完成后,模式串应该向后滑动多少. 和上一题 HDU 1686 不同,两个图 ...

  4. HDU 1711 kmp+离散化

    http://acm.hdu.edu.cn/showproblem.php?pid=1711 Number Sequence Time Limit: 10000/5000 MS (Java/Other ...

  5. HDU 2203 kmp

    http://acm.hdu.edu.cn/showproblem.php?pid=2203 亲和串 Time Limit: 3000/1000 MS (Java/Others)    Memory ...

  6. hdu 2087 kmp

    http://acm.hdu.edu.cn/showproblem.php?pid=2087 算是模板题吧,找到一个子串之后将模板串指针归零否则会重复计算. #include<bits/stdc ...

  7. Cyclic Nacklace HDU - 3746 (kmp)

    Cyclic Nacklace Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  8. hdu 1711 KMP算法模板题

    题意:给你两个串,问你第二个串是从第一个串的什么位置開始全然匹配的? kmp裸题,复杂度O(n+m). 当一个字符串以0为起始下标时.next[i]能够描写叙述为"不为自身的最大首尾反复子串 ...

  9. hdu poj KMP简单题目总结

    hdu 3336 题意:输入一个字符串求每个前缀在串中出现的次数和 sol:只要稍微理解下next 数组的含义就知道只要把每个有意义的next值得个数加起来即可 PS:网上有dp解法orz,dp[i] ...

随机推荐

  1. 对于Mobile模块化的概念认知(小白)

    最近刚刚学习了Mobile的一些基础知识,把它整理一下方便自己的学习 那什么是Mobile呢? 自己的理解是将一个项目中共同的部分抽出来,这样就形成了Mobile模块. 为什么要使用Mobile呢? ...

  2. linux安装/卸载mysql

    其实安装mysql差不多有10次了吧, 但是每次都有坑,各种百度,太麻烦了,所以这次把坑给记录下来,下次直接用. 1. 去官网下载mysql.这里可以使用wget下载.先去官方网站,找到mysql5. ...

  3. Java使用Cipher类实现加密,包括DES,DES3,AES和RSA加密

    一.先看一个简单加密,解密实现 1.1 加密 /** * content: 加密内容 * slatKey: 加密的盐,16位字符串 * vectorKey: 加密的向量,16位字符串 */ publi ...

  4. 345 Reverse Vowels of a String 反转字符串中的元音字母

    编写一个函数,以字符串作为输入,反转该字符串中的元音字母.示例 1:给定 s = "hello", 返回 "holle".示例 2:给定 s = "l ...

  5. 笨拙而诡异的 Oracle

    有这样一段 SQL 代码: 通过 C# 获取查询结果:    SQL 代码中有两个参数,且都是字符串类型,以上的 C# 代码是生成 Oracle SQL 代码所需要的参数.运行结果如下:   居然发生 ...

  6. SQL基本操作——JOIN多表联查

    基本概念 join :用于根据两个或多个表中的列之间的关系,从这些表中查询数据. join和key:有时为了得到完整的结果,我们需要从两个或更多的表中获取结果.我们就需要执行 join.数据库中的表可 ...

  7. 史上巨坑: vim的"set foldmethod=syntax"设置竟然是导致ctrl+p(ctrl+n)补全在文件稍大时光标位于中间位置补全效率变慢的元凶!

    最近我的vim又让我闹心了. 问题出现在supertab的补全速度上, 有时候按下tab键半天才弹出补全列表, 即便是弹出了列表在列表上下移动也变得的相当缓慢, 这让我的很是蛋疼. 在完全无法接受这个 ...

  8. (转)Java任务调度框架Quartz入门教程指南(四)Quartz任务调度框架之触发器精讲SimpleTrigger和CronTrigger、最详细的Cron表达式范例

    http://blog.csdn.net/zixiao217/article/details/53075009 Quartz的主要接口类是Schedule.Job.Trigger,而触发器Trigge ...

  9. 太坑了,mybatis注解一对多,id没了

    @Select("SELECT *, id nodes FROM QUESTION_PO WHERE ID=#{id}") @Results({ @Result(property ...

  10. ubuntu下查看如何配置pycharm

    ubuntu中PyCharm的安装与卸载 https://blog.csdn.net/weixin_31484477/article/details/81133590 pycharm ModuleNo ...