判断字符串“同构”的技巧

题目大意

给定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的更多相关文章

  1. 小技巧--字符串输入从a[1]开始

    char a[100],b[100]; cin>>a>>(b+1);//cin: abcd abcd cout<<a[1]<<endl<<b ...

  2. Javascript字符串拼接小技巧

    在Javascript中经常会遇到字符串的问题,但是如果要拼接的字符串过长就比较麻烦了. 如果是在一行的,可读性差不说,如果要换行的,会直接报错. 在此介绍几种Javascript拼接字符串的技巧. ...

  3. LeetCode 205:同构字符串 Isomorphic Strings

    题目: 给定两个字符串 s 和 *t*,判断它们是否是同构的. 如果 s 中的字符可以被替换得到 *t* ,那么这两个字符串是同构的. 所有出现的字符都必须用另一个字符替换,同时保留字符的顺序.两个字 ...

  4. 字符串最小表示法 O(n)算法

    网上看了这篇文章后还是感觉有些地方讲的没有详细的证明所以添加了一点 红色字是博主写的 求字符串的循环最小表示: 上面说的两个字符串同构的,并没有直接先求出Min(s),而是通过指针移动,当某次匹配串长 ...

  5. LeetCode刷题指南(字符串)

    作者:CYC2018 文章链接:https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/Leetcode+%E9%A2%98%E8%A7% ...

  6. HASH 字符串哈希 映射转化

    哈希HASH的本质思想类似于映射.离散化. 哈希,通过给不同字符赋不同的值.并且钦定一个进制K和模数,从而实现一个字符串到一个模意义下的K进制数上. 它的主要目的是判重,用于$DFS$.$BFS$判重 ...

  7. 字符串的最小最大表示法O(n)

    以下介绍内容内容转自:http://blog.csdn.net/zy691357966/article/details/39854359 网上看了这篇文章后还是感觉有些地方讲的没有详细的证明所以添加了 ...

  8. 【转载】字符串最小表示法-O(n)算法

    原博客链接:http://blog.csdn.net/zy691357966/article/details/39854359 未授权,侵权删. 因为这篇博客写得真好..转载了.. 红色的字是原博主写 ...

  9. Leedcode算法专题训练(字符串)

    4. 两个字符串包含的字符是否完全相同 242. Valid Anagram (Easy) Leetcode / 力扣 可以用 HashMap 来映射字符与出现次数,然后比较两个字符串出现的字符数量是 ...

随机推荐

  1. 第二章 "我要点爆"微信小程序点爆页面的实现与云函数和云存储的应用

    点爆页面的实现与云函数和云存储的应用以及录音功能讲解 点爆页面制作 点爆页面主要提供文字记录和语音记录两种爆文记录方式,在本页面内输入文字或录入语音后选择心情点击点爆按钮,跳转到点爆方式选择界面. 首 ...

  2. bzoj1142:[POI2009]Tab

    传送门 考虑每次交换都不会改变每个数所在的行和列(不是指编号,而是指和它在同一行或者同一列的数不会发生变化) 由于每个数互不相同,所以记录下每个数所在的行和列,暴力判断就好了 代码: #include ...

  3. seq(2018.10.24)

    一道\(dp\)题... 期望\(40\)分解法 预处理:离散化,然后让连续一段值相同的元素合并为一个元素. 正式\(DP\): 显然有个最差策略为每个元素处都切一次,则切的次数为元素的个数\(-1\ ...

  4. FMDB存储模型对象(以二进制存储)用NSKeyedArchiver archivedDataWithRootObject序列号,NSKeyedUnarchiver unarchiveObjectWithData反序列化(重点坑是sql语句@"insert into t_newsWithChannel (nwesName,newsType) values (?,?)")一定要用占位符

    交友:微信号 dwjluck2013 一.封装FMDB单例 (1)JLFMDBHelp.h文件 #import <Foundation/Foundation.h> #import < ...

  5. mysql_innodb引擎

    innodb概括 1.Innodb是一种事务性存储引擎 2.完全支持事务的ACID特性 3.实现事务特性的原理: 使用Redo Log和Undo Log,Undo Log用于帮助未提交事务进行回滚,R ...

  6. Technocup 2017 - Elimination Round 1 (Unofficially Open for Everyone, Rated for Div. 2) C

    This is an interactive problem. You should use flush operation after each printed line. For example, ...

  7. jquery.validate自定义验证--成功提示与择要提示

    1. 自定义验证--成功提示 1) 添加选项 errorClass: "unchecked", validClass: "checked", errorElem ...

  8. Java GUI 顶级容器JFrame、JDialog

    JFrame的常用构造函数: JFrame() JFrame(String title)   //窗口标题,会显示在左上角窗体图标的后面 JDialog的常用构造函数: JDialog() JDial ...

  9. 《高性能MySQL》读书笔记之创建高性能的索引

    索引是存储引擎用于快速找到记录的一种数据结构.索引优化是对查询性能优化的最有效手段.索引能够轻易将查询性能提高几个数量级.创建一个最优的索引经常需要重写查询.5.1 索引基础 在MySQL中,存储引擎 ...

  10. postgresql 存储过程动态更新数据

    -- 目标:动态更新表中数据 -- 老规矩上代码-----------------------------tablename 表名--feildname 字段名数组--feildvalue 字段值数组 ...