【技巧:字符串同构】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 来映射字符与出现次数,然后比较两个字符串出现的字符数量是 ...
随机推荐
- 详解什么是redis
企业中redis是必备的性能优化中间件,也是常见面试题,首先Redis是由意大利人Salvatore Sanfilippo(网名:antirez)开发的一款内存高速缓存数据库.Redis全称为:Rem ...
- VRTK3.3.0-004传送
直线传送: 一.无高度变换传送(VRTK_BasicTeleport) 1丶继续在VRScripts下创建空物体PlayArea,用来挂在传送相关脚本:创建Plane作为传送地面 2丶在PlayAre ...
- C 语言实例 - 计算 int, float, double 和 char 字节大小
C 语言实例 - 计算 int, float, double 和 char 字节大小 C 语言实例 C 语言实例 使用 sizeof 操作符计算int, float, double 和 char四种变 ...
- 初学Java web(转)
转自 http://www.oschina.net/question/12_52027 OSCHINA 软件库有一个分类——Web框架,该分类中包含多种编程语言的将近500个项目. Web框架是开发者 ...
- 安装CocoaPods,ios的库安装工具
1.需要ruby环境,mac pro自带了 2.终端输入:sudo gem install cocoapods
- A - Bi-shoe and Phi-shoe
每一个数字的欧拉函数要大于或等于该数字.求,最小的欧拉函数的下标和的大小. 答案要用longlong存 #include <iostream> #include <algorithm ...
- C# 基础之字段与属性
1.属性是字段的扩展 2.根据面向对象封装思想,字段最好设为private(私有),这样有利于防止客户端对字段的篡改,从而保证了成员的完整性 3.访问类中私有字段,C#提供了属性,用来对字段进行灵活的 ...
- urllib库的基本使用
urllib库的使用 官方文档地址:https://docs.python.org/3/library/urllib.html 什么是urllib Urllib是python内置的HTTP请求库包括以 ...
- NOIP前计划
距离NOIp还有13天 距离继续学/退役还有13天 是时候列一波计划了 1. 要学的东西 cdq分治(突然发现cdq分治不太行,而且说不定可以用来代替想不出来的数据结构题) 主席树(写的太少啦,不熟练 ...
- Codeforces Round #396 (Div. 2) B
Mahmoud has n line segments, the i-th of them has length ai. Ehab challenged him to use exactly 3 li ...