【技巧:字符串同构】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 来映射字符与出现次数,然后比较两个字符串出现的字符数量是 ...
随机推荐
- 大数据技术之_27_电商平台数据分析项目_02_预备知识 + Scala + Spark Core + Spark SQL + Spark Streaming + Java 对象池
第0章 预备知识0.1 Scala0.1.1 Scala 操作符0.1.2 拉链操作0.2 Spark Core0.2.1 Spark RDD 持久化0.2.2 Spark 共享变量0.3 Spark ...
- dubbo-admin安装
1.下载dubbo-adminhttps://github.com/apache/incubator-dubbo/tree/dubbo-2.5.7 2.解压,进入到/home/zhanxuewei/D ...
- 黑马Stream流学习 Stream流 函数式接口 Lambda表达式 方法引用
- jar工具的使用
- Sublime text3 插件ColorPicker(调色板)不能使用快捷键
我的原因是: convertToUTF8 和 ColorPicker 快捷键冲突,convertoUTF8的默认转换GBK的快捷键 和 ColorPicker打开调色板的快捷键都是ctrl+shift ...
- Qt 进程和线程之一:运行一个进程和进程间通信
Qt提供了对进程和线程的支持.本节讲述了怎样在Qt应用程序中启动一个进程,以及几种常用的进程间通信方法.如果对进程和线程的概念不是很了解,可以看我的另一篇博客:[多进程和多线程的概念. 设计应用程序时 ...
- Java中的list与Set、Map区别及适用场景
Collection接口是集合类的根接口,Java中没有提供这个接口的直接的实现类,但是却让其被继承产生了两个接口,就是Set和List.Set中不能包含重复的元素.List是一个有序的集合,可以包含 ...
- .NET Core 1.0 CentOS7 尝试(二、VSCode安装)
晚上继续摸索~~ 一.VSCode安装 下载VSCode,地址:https://code.visualstudio.com/Docs/?dv=linux64_rpm 直接双击安装或者使用rpm -i ...
- 起学习iOS开发专用词汇
今天的单词分别是: l Asynchronous 形容词 异步的 n 副词形式: asynchronously 异步地 n 缩写:ASYNC n 反义词:synchronous 形容词同步 ...
- GoAccess参数选项
GoAccess - 1.2 Usage: goaccess [filename] [ options ... ] [-c][-M][-H][-q][-d][...]The following opt ...