bzoj4641 基因改造 KMP / hash

依稀记得,$NOIP$之前的我是如此的弱小....
完全不会$KMP$的写法,只会暴力$hash$....
大体思路为把一个串的哈希值拆成$26$个字母的位权
即$hash(S) = \sum\limits_{a} a * \sum w^i * [s[i] == a]$
通过记录每个字母第一次出现的位置,用$26$的时间来确定$f$是什么
然后通过确定的$f$计算出$f$是正确的时候的$hash$值,和原串的$hash$值比较
复杂度$O(26n)$
自然取模....
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
namespace remoon {
#define ri register int
#define ll long long
#define ull unsigned long long
#define rep(io, st, ed) for(ri io = st; io <= ed; io ++)
#define drep(io, ed, st) for(ri io = ed; io >= st; io --)
}
using namespace std;
using namespace remoon; #define sid 500050
char s[], t[sid]; int n, m, tim, f[];
int num[], vis[], nxt[], tot;
ull val[], wei[sid];
ull seed = ; inline void Init() {
wei[] = ;
rep(i, , m) wei[i] = wei[i - ] * seed;
rep(i, , m) {
int le = t[i];
if(!vis[le]) nxt[++ tot] = i, vis[le] = ;
val[le] += wei[m - i];
}
tim ++;
} inline void Solve() {
ull now = , tval = ;
rep(i, , m) now += s[i] * wei[m - i];
rep(i, m, n) { tim ++;
int flag = ; rep(j, , tot) {
int v = s[i - m + nxt[j]];
if(vis[v] == tim) { flag = ; break; }
if(vis[v] != tim) vis[v] = tim;
f[j] = v;
} if(!flag) {
tval = ;
rep(j, , tot)
tval += f[j] * val[t[nxt[j]]];
if(tval == now) write(i - m + );
} now -= s[i - m + ] * wei[m - ];
now *= seed; now += s[i + ];
}
} int main() {
scanf("%s", s + ); n = strlen(s + );
scanf("%s", t + ); m = strlen(t + );
Init(); Solve();
return ;
}
现在我明白了$KMP$是非常伟大的算法....
对于此题而言,考虑每个字符的上一个字符离当前字符的距离,这可以成为一个新串
然后比对新串即可
特别的,如果上一个字符出现的位置超过了匹配长度,那么我们也要视作合法
但是,我们发现这种匹配满足有前效性,没有后效性,因此可以用$KMP$
复杂度$O(n)$,十分的优秀
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
namespace remoon {
#define ri register int
#define rep(io, st, ed) for(ri io = st; io <= ed; io ++)
#define drep(io, ed, st) for(ri io = ed; io >= st; io --)
}
using namespace std;
using namespace remoon; const int sid = ; int n, m;
char s[sid], t[sid];
int lst[], S[sid], T[sid], nxt[sid]; inline bool match(int x, int y) {
if(y > m) return ;
if(x == T[y]) return ;
if(!T[y] && x >= y) return ;
return ;
} int main() {
scanf("%s", s + ); scanf("%s", t + );
n = strlen(s + ); m = strlen(t + ); rep(i, , n) {
S[i] = lst[s[i]] ? i - lst[s[i]] : ;
lst[s[i]] = i;
} memset(lst, , sizeof(lst));
rep(i, , m) {
T[i] = lst[t[i]] ? i - lst[t[i]] : ;
lst[t[i]] = i;
} for(ri i = , j = ; i <= m; i ++) {
while(j && !match(T[i], j + )) j = nxt[j];
if(match(T[i], j + )) j ++;
nxt[i] = j;
} for(ri i = , j = ; i <= n; i ++) {
while(j && !match(S[i], j + )) j = nxt[j];
if(match(S[i], j + )) j ++;
if(j == m) printf("%d\n", i - m + );
}
return ;
}
bzoj4641 基因改造 KMP / hash的更多相关文章
- BZOJ4641 基因改造[KMP]
这道题以前好像模拟的时候做过,当时不会做,于是用hash水过去了.. 正解是KMP,还是用当前字符与上一次相同字符位置的距离表示数组,于是数值相等时就代表相似.第一次出现用INF代替. 然后要匹配有多 ...
- 【BZOJ4641】基因改造 KMP
[BZOJ4641]基因改造 Description "人类智慧的冰峰,只有萌萌哒的我寂寞地守望." --TB TB正走在改造人类智慧基因的路上.TB发现人类智慧基因一点也不萌萌哒 ...
- Codeforces 1090J $kmp+hash+$二分
题意 给出两个字符串\(s\)和\(t\),设\(S\)为\(s\)的任意一个非空前缀,\(T\)为\(t\)的任意一个非空前缀,问\(S+T\)有多少种不同的可能. Solution 看了一圈,感觉 ...
- 【bzoj4641】基因改造 特殊匹配条件的KMP
题目描述 如果两个长度相等的字符串,如果存在一种字符的一一映射,使得第一个字符串的所有字符经过映射后与第二个字符串相同,那么就称它们“匹配”.现在给出两个串,求第一个字符串所有长度等于第二个字符串的长 ...
- 【BZOJ3940】【BZOJ3942】[Usaco2015 Feb]Censoring AC自动机/KMP/hash+栈
[BZOJ3942][Usaco2015 Feb]Censoring Description Farmer John has purchased a subscription to Good Hoov ...
- 【POJ2185】【KMP + HASH】Milking Grid
Description Every morning when they are milked, the Farmer John's cows form a rectangular grid that ...
- HDU 5782 Cycle(KMP+Hash)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5782 [题目大意] 给出两个字符串,判断他们每一个前缀是否循环同构,循环同构的意思就是,字符串首位 ...
- Cycle (KMP + hash)
题意:给你2个串,让你判断2个字符串的前缀是否满足首尾连接形成的环是不是一样的. 思路:我们需要提前知道的是满足条件的前缀一定满足 strA = str1 + str2, strB = str2 + ...
- 7.26机房报零赛——无尽的矩阵【kmp+hash】
恩,其实大家都没有报零,反正我是蒟蒻 为了纪念我第一次打过哈希,特此写一篇题解 题目描述 从前有一个的小矩阵,矩阵的每个元素是一个字母(区分大小写),突然有一天它发生了 变异,覆盖了整个二维空间,即不 ...
随机推荐
- linux系统文件
关于linux系统文件命令 (1)Linux的文件系统目录配置要遵循FHS规范,规范定义的两级目录规范如下: /home 每个账号在该目录下都有一个文件夹,进行数据的管理 ...
- 使用mysql的SUBSTRING_INDEX函数解决项目中编码非重复问题的实现方案!
一 SUBSTRING_INDEX函数介绍 作用:按关键字截取字符串 substring_index(str,delim,count) 说明:substring_index(被截取字段,关键字,关键字 ...
- pyquery学习笔记
很早就听说了pyquery的强大.写了个简单的测试程序实验下. 思路是找个动态网页,先用PhantomJS加载,然后用PYQUERY解析. 1.随便找了个带表格的股票网页,里面有大量的股票数据,测试的 ...
- 使用qshell备份七牛云存储文件
qshell是利用七牛文档上公开的API实现的一个方便开发者测试和使用七牛API服务的命令行工具.我们可以利用它来将七牛云上存储的文件备份到本地. 它提供Mac OSX, Linux, Windows ...
- python基础学习之路No.5 数学函数以及操作
python的基本数学函数 函数 返回值 ( 描述 ) abs(x) 返回数字的绝对值,如abs(-10) 返回 10 ceil(x) 返回数字的上入整数,如math.ceil(4.1) 返回 5 c ...
- SQLSERVER 2008 编辑所有或者任意行
选中表 右键选择“编辑前200行”,然后选择左上角的 sql图标,然后在右侧的SQL语句去掉 top 200 然后执行查询 就可以编辑所有的行了,可以选择自己需要写SQL,然后查询编辑. 第二种方法: ...
- 一键开关VS的release模式优化
因为我们公司的项目规模非常大了,如果日常调试使用debug模式的话,每次调试启动都要非常长的时间,因此大多数人使用release关优化的方式来进行日常开发.但是因为持续集成的存在,上传的代码要求是开启 ...
- **iOS发JSON请求中字符串加转义,返回的JSON去转义
iOS中使用NSSerialization把对象转为JSON字符串后,多出来反斜杠的问题 http://segmentfault.com/q/1010000000576646 NSDictionary ...
- 安装VM虚拟机提示 尝试创建目录 C:\Public\documents\SharedVirtual Machines 时发生错误解决方法
把Windows Defender安全中心的“受控制文件夹的访问”给关闭了,然后就可以顺利安装上了. 作者:耑新新,发布于 博客园 转载请注明出处,欢迎邮件交流:zhuanxinxin@foxmai ...
- .NETCore分布式微服务站点设计(1)-概念图
自己画了一个简略结构图,准备按照这个搭建一套微服务型的站点 利用Identityserver4+Redis+Sqlserver+Swagger+阿里云OSS+RabbitMQ+Nginx来实现,按照自 ...