【技巧:字符串同构】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 来映射字符与出现次数,然后比较两个字符串出现的字符数量是 ...
随机推荐
- __str__,__repr__
目录 __str__ __repr__ __str__ 打印时触发 class Foo: pass obj = Foo() print(obj) <__main__.Foo object at ...
- 部署spark 1.3.1 standalong模式
之前已经写过很多次部署spark 的博客,但是之前部署都是照瓢画葫芦,不得其中的细节,并且以前都是部署spark on yarn 部署环境 scala 2.10.2,jdk 1.6,spark 版本1 ...
- 51Nod 1272 最大距离 (栈或贪心)
#include <cstdio> #include <queue> #include <cstring> #include <iostream> #i ...
- js_jquery
引用 jQuery 是一个 JavaScript 库,不需要安装,直接引用就行 <!-- jQuery --> <script src="/static/vendors/j ...
- netty与MQ使用心得
最近在做分布式的系统,使用netty与mq进行远程RPC调用,现将心得经验总结一下. 我们公司的服务器在云端机房,在每一个店面有一个服务器,店面服务器外网无法访问. 我们的做法是店面服务器在启动时与云 ...
- [WOJ4354] 蜀石经
题目链接: 点我 题目分析: 大模拟,貌似\(O(n^2)\)也可以卡常过,复杂度正确的做法是用优先队列维护. 代码: #include<bits/stdc++.h> #define N ...
- centOS 部署服务器(三)
今天一个新的项目终于能够重新安装mysql了,分享下步骤: 1.下载地址:http://dev.mysql.com/downloads/mysql/ (选择Linux - Generic版本的Lin ...
- mysql合服 更新相同的用户名前追加服务器编号
表结构: CREATE TABLE IF NOT EXISTS `user` ( `) NOT NULL COMMENT '主键', `user_level` ) COMMENT '等级', `) C ...
- Oracle 修改密码(忘记登录密码,用户System)
1.修改计算机环境变量,把oracle服务端路径放在最前面 2.输入cmd 3.输入命令:sysplus /nolog SQL>conn sys/syspwd as sysdba SQL> ...
- 2019/05/11 JAVA虚拟机原理
所谓虚拟机,就是一台虚拟的机器.他是一款软件,用来执行一系列虚拟计算指令,大体上虚拟机可以分为 系统虚拟机和程序虚拟机, 大名鼎鼎的Visual Box.Vmare就属于系统虚拟机,他们完全是对物理计 ...