【技巧:字符串同构】Avendesora
判断字符串“同构”的技巧
题目大意
给定A,B两个序列,要求B在A中出现的次数以及位置。定义字符变换:把所有相同的字符变为另一种字符;两个字符串相等:当且仅当一个字符串可以在若干次字符变换之后变为另一个字符串。
题目分析
如果没有这个“字符变换”的条件,显然就是裸的KMP题。
不过有一种判断同构的方法:将数列权值转为它离之前最近相同元素的距离。
用$lst[i]$表示$a[i]$元素前的最近元素位置,就是$a[i]=i-lst[i]$。
那么再接下去做kmp就好了。
#include<bits/stdc++.h>
const int maxn = ; int T,c,n,m;
int a[maxn],b[maxn],lsta[maxn],lstb[maxn],pre[maxn];
int fail[maxn];
int ans[maxn]; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch = getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch = getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
int main()
{
freopen("ex_t2.in","r",stdin);
T = read(), c = read();
while (T--)
{
memset(fail, , sizeof fail);
memset(pre, , sizeof pre);
ans[] = , n = read(), m = read();
for (int i=; i<=n; i++)
{
a[i] = read();
lsta[i] = pre[a[i]];
pre[a[i]] = i;
}
memset(pre, , sizeof pre);
for (int i=; i<=m; i++)
{
b[i] = read();
lstb[i] = pre[b[i]];
pre[b[i]] = i;
}
for (int i=, j=; i<m; i++)
{
while (j&&lstb[j+]!=std::max(lstb[i+]-i+j, )) j = fail[j];
if (lstb[j+]==std::max(lstb[i+]-i+j, )) j++;
fail[i+] = j;
}
for (int i=, j=; i<n; i++)
{
while (j&&lstb[j+]!=std::max(lsta[i+]-i+j, )) j = fail[j];
if (lstb[j+]==std::max(lsta[i+]-i+j, )) j++;
if (j==m){
ans[++ans[]] = i-m+;
j = fail[j];
}
}
printf("%d\n",ans[]);
for (int i=; i<=ans[]; i++) printf("%d ",ans[i]);
puts("");
}
return ;
}
END
【技巧:字符串同构】Avendesora的更多相关文章
- 小技巧--字符串输入从a[1]开始
char a[100],b[100]; cin>>a>>(b+1);//cin: abcd abcd cout<<a[1]<<endl<<b ...
- Javascript字符串拼接小技巧
在Javascript中经常会遇到字符串的问题,但是如果要拼接的字符串过长就比较麻烦了. 如果是在一行的,可读性差不说,如果要换行的,会直接报错. 在此介绍几种Javascript拼接字符串的技巧. ...
- LeetCode 205:同构字符串 Isomorphic Strings
题目: 给定两个字符串 s 和 *t*,判断它们是否是同构的. 如果 s 中的字符可以被替换得到 *t* ,那么这两个字符串是同构的. 所有出现的字符都必须用另一个字符替换,同时保留字符的顺序.两个字 ...
- 字符串最小表示法 O(n)算法
网上看了这篇文章后还是感觉有些地方讲的没有详细的证明所以添加了一点 红色字是博主写的 求字符串的循环最小表示: 上面说的两个字符串同构的,并没有直接先求出Min(s),而是通过指针移动,当某次匹配串长 ...
- LeetCode刷题指南(字符串)
作者:CYC2018 文章链接:https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/Leetcode+%E9%A2%98%E8%A7% ...
- HASH 字符串哈希 映射转化
哈希HASH的本质思想类似于映射.离散化. 哈希,通过给不同字符赋不同的值.并且钦定一个进制K和模数,从而实现一个字符串到一个模意义下的K进制数上. 它的主要目的是判重,用于$DFS$.$BFS$判重 ...
- 字符串的最小最大表示法O(n)
以下介绍内容内容转自:http://blog.csdn.net/zy691357966/article/details/39854359 网上看了这篇文章后还是感觉有些地方讲的没有详细的证明所以添加了 ...
- 【转载】字符串最小表示法-O(n)算法
原博客链接:http://blog.csdn.net/zy691357966/article/details/39854359 未授权,侵权删. 因为这篇博客写得真好..转载了.. 红色的字是原博主写 ...
- Leedcode算法专题训练(字符串)
4. 两个字符串包含的字符是否完全相同 242. Valid Anagram (Easy) Leetcode / 力扣 可以用 HashMap 来映射字符与出现次数,然后比较两个字符串出现的字符数量是 ...
随机推荐
- 利用多项式实现图像几何校正(Matlab实现)
1.原理简述: 根据两幅图像中的一些已知对应点(控制点对),建立函数关系式,通过坐标变换,实现失真图像的几何校正. 设两幅图像坐标系统之间畸变关系能用解析式来描述: 根据上述的函数关系,可以依 ...
- assembly x86(nasm)串比较
预留字符串口令,输入口令串与预留密码串比较.若匹配则显示“MATCH!CONGRATULATION”,否则显示“NOMATCH!”,并让用户重新输入,程序能对口令进行测试,但测试次数最多3次,若3次输 ...
- echarts散点图重叠
今天做echarts图标,使用了散点图.很快实现,发现数据不对,应该是3个的企业,页面只显示了2个,查了半天才发现原来是有两个重叠了.想办法解决了,在网上费劲九牛二虎只力终于找到了解决的方法,下面来解 ...
- VC 中TEXT、_T、L的区别
http://i.cnblogs.com/EditPosts.aspx?opt=1 对于从VC++6.0转到VS2005编译环境中的程序员.往往会碰到字符集之间的转换. VC6.0采用的是ANSI字符 ...
- [模板](luogu P3387)縮點
前言:對於這週的咕咕咕表示好像沒什麼好表示的,完全沒有靈感a......寫東西真的好難啊......於是又玩了半天鬼泣4???還挺好玩的 來源:題解 题目背景 缩点+DP 题目描述 给定一个n个点m条 ...
- 如何在VirtualBox虚拟机中安装XP系统? 转
关闭VM (windows 7 )的方法, 使用 退出 保持状态 开启VM (windows 7 )的方法, 选择启动 ######Iissue 1 网络连接不上,可以重新初始化 网络连接. #### ...
- 移动端 Web 网页调试技巧
原文出处: 盛瀚钦 本文主要列举了调试本地网页.查看测试环境网页的各种方法,涵盖了PC.iPad.移动端的调试技巧. 本文的不足之处在于,小溪里暂时还没有找到调试位于微信中和安卓各国产浏览器上的网页. ...
- Haproxy常见用法
简介 HAProxy 提供高可用性.负载均衡以及基于 TCP 和 HTTP 应用的代理,支持虚拟主机, 它是免费.快速并且可靠的一种解决方案. HAProxy 特别适用于那些负载特大的 web 站点, ...
- Memcached 未授权访问漏洞及加固
memcached是一套分布式的高速缓存系统.它以Key-Value(键值对)形式将数据存储在内存中,这些数据通常是应用读取频繁的.正因为内存中数据的读取远远大于硬盘,因此可以用来加速应用的访问. 漏 ...
- JavaScript单元测试框架:Jasmine
摘抄:http://blog.csdn.net/GuoJiangweigege/article/details/52130589 互联网的快速发展,给web开发人员带来了前所未有的挑战.对于前端开发, ...