传送门

每次操作可以把两个字符串中所有同一种字符变成另外一种

定义两个长度相等的字符串之间的距离为:使两个字符串相等所需要操作的次数的最小值

求 \(s\) 中每一个长度为 \(|t|\) 的连续子串与 \(t\) 的距离

字符集为小写字母 \('a'\) 到 \('f'\)

Sol

考虑如何计算两个等长串的距离

相当于两个匹配的字符之间连边,同一个连通块内可以互相转化,答案就是并查集合并的次数

本题的字符集大小只有 \(6\),那么考虑枚举两种字符匹配连边

匹配就是一个非常套路的反转 \(+\) \(FFT\) 了

# include <bits/stdc++.h>
using namespace std;
typedef long long ll; const int maxn(1 << 18);
const double pi(acos(-1)); struct Complex {
double a, b; inline Complex() {
a = b = 0;
} inline Complex(double _a, double _b) {
a = _a, b = _b;
} inline Complex operator +(Complex x) const {
return Complex(a + x.a, b + x.b);
} inline Complex operator -(Complex x) const {
return Complex(a - x.a, b - x.b);
} inline Complex operator *(Complex x) const {
return Complex(a * x.a - b * x.b, a * x.b + b * x.a);
} inline Complex Conj() {
return Complex(a, -b);
}
}; Complex a[maxn], b[maxn], w[maxn];
int r[maxn], l, deg, g[maxn], h[maxn], cnt[maxn]; inline void FFT(Complex *p, int opt) {
register int i, j, k, t;
register Complex wn, x, y;
for (i = 0; i < deg; ++i) if (r[i] < i) swap(p[r[i]], p[i]);
for (i = 1; i < deg; i <<= 1)
for(t = i << 1, j = 0; j < deg; j += t)
for (k = 0; k < i; ++k) {
wn = w[deg / i * k];
if (opt == -1) wn.b *= -1;
x = p[j + k], y = wn * p[i + j + k];
p[j + k] = x + y, p[i + j + k] = x - y;
}
} inline void Init(int n) {
register int i;
for (deg = 1, l = 0; deg < n; deg <<= 1) ++l;
for (i = 0; i < deg; ++i) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
for (i = 0; i < deg; ++i) w[i] = Complex(cos(pi * i / deg), sin(pi * i / deg));
} inline void Mul(int *p, int *q, int *f) {
register int i, k;
register Complex ca, da, db;
for (i = 0; i < deg; ++i) a[i] = Complex(p[i], q[i]);
for (FFT(a, 1), i = 0; i < deg; ++i) {
k = (deg - i) & (deg - 1), ca = a[k].Conj();
b[i] = (ca + a[i]) * (a[i] - ca) * Complex(0, -0.25);
}
for (FFT(b, -1), i = 0; i < deg; ++i) f[i] = (int)(b[i].a / deg + 0.5);
} int n, m, mp[7][7][maxn], fa[7], ans;
char s[maxn], t[maxn]; inline int Find(int x) {
return fa[x] == x ? x : fa[x] = Find(fa[x]);
} int main() {
register int i, j, k, d;
scanf(" %s %s", s + 1, t + 1), n = strlen(s + 1), m = strlen(t + 1);
reverse(t + 1, t + m + 1), Init(n + m + 1), d = n - m + 1;
for (i = 1; i <= 6; ++i)
for (j = 1; j <= 6; ++j)
if (i != j) {
for (k = 1; k <= n; ++k) g[k] = s[k] - 'a' + 1 == i;
for (k = 1; k <= m; ++k) h[k] = t[k] - 'a' + 1 == j;
for (Mul(g, h, cnt), k = 1; k <= d; ++k) mp[i][j][k] = cnt[m + k] > 0;
}
for (i = 1; i <= d; ++i) {
for (ans = 0, j = 1; j <= 6; ++j) fa[j] = j;
for (j = 1; j <= 6; ++j)
for (k = 1; k <= 6; ++k)
if (mp[j][k][i] && (Find(j) ^ Find(k))) ++ans, fa[Find(j)] = Find(k);
printf("%d ", ans);
}
return 0;
}

CF954I Yet Another String Matching Problem的更多相关文章

  1. CF954I Yet Another String Matching Problem 并查集、FFT

    传送门 题意:给出两个由小写$a$到$f$组成的字符串$S$和$T$($|S| \geq |T|$),给出变换$c1\,c2$表示将两个字符串中所有$c1$字符变为$c2$,求$S$的每一个长度为$T ...

  2. CF954I Yet Another String Matching Problem(FFT+并查集)

    给定两个字符串\(S,T\) 求\(S\)所有长度为\(|T|\)子串与\(T\)的距离 两个等长的串的距离定义为最少的,将某一个字符全部视作另外一个字符的次数. \(|T|<=|S|<= ...

  3. 【CF954I】Yet Another String Matching Problem(FFT)

    [CF954I]Yet Another String Matching Problem(FFT) 题面 给定两个字符串\(S,T\) 求\(S\)所有长度为\(|T|\)的子串与\(T\)的距离 两个 ...

  4. Educational Codeforces Round 40 I. Yet Another String Matching Problem

    http://codeforces.com/contest/954/problem/I 给你两个串s,p,求上一个串的长度为|p|的所有子串和p的差距是多少,两个串的差距就是每次把一个字符变成另一个字 ...

  5. 954I Yet Another String Matching Problem

    传送门 分析 我们先考虑暴力如何计算 对于S的子串SS,如果它有位置i使得SS[i] != T[i]那么我们就将两个字符之间用并查集连边 最后答案很明显就是并查集中所有边的个数 于是我们可以发现对于S ...

  6. Codeforces 954I Yet Another String Matching Problem(并查集 + FFT)

    题目链接  Educational Codeforces Round 40  Problem I 题意  定义两个长度相等的字符串之间的距离为:   把两个字符串中所有同一种字符变成另外一种,使得两个 ...

  7. Codeforces.954I.Yet Another String Matching Problem(FFT)

    题目链接 \(Description\) 对于两个串\(a,b\),每次你可以选择一种字符,将它在两个串中全部变为另一种字符. 定义\(dis(a,b)\)为使得\(a,b\)相等所需的最小修改次数. ...

  8. string matching(拓展KMP)

    Problem Description String matching is a common type of problem in computer science. One string matc ...

  9. NYOJ之Binary String Matching

    Binary String Matching 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述     Given two strings A and B, whose a ...

随机推荐

  1. Java性能优化技巧及实战

    关于Java代码的性能优化,是每个javaer都渴望掌握的本领,进而晋升为大牛的必经之路,但是对java的调优需要了解整个java的运行机制及底层调用细节,需要多看多读多写多试,并非一朝一夕之功.本文 ...

  2. django model改变后,同步数据库

    在使用django进行开发时,往往需要根据不同的需求对model进行更改.而这时候,python manage.py syncdb就不好使了. 目前有个很好的工具,是south,这个是专门用来更改mo ...

  3. Laravel - 从百草园到三味书屋 "From Apprentice To Artisan"目录

    Laravel - 从百草园到三味书屋 "From Apprentice To Artisan"目录 https://my.oschina.net/zgldh/blog/38924 ...

  4. XMPPFramework核心类介绍

    XMPPFramework结构 在进入下一步之前,先给大家讲讲XMPPFramework的目录结构,以便新手们更容易读懂文章.我们来看看下图: 虽然这里有很多个目录,但是我们在开发中基本只关心Core ...

  5. np.array()和np.mat()区别

    1. 生成数组所需格式不同 mat可以从字符串或列表中生成:array只能从列表中生成 2. 生成的数组计算方式不同 array生成数组,用np.dot()表示矩阵乘积,(*)号或np.multipl ...

  6. Mac 10.12安装Google浏览器

    说明:先安装旧版本后续再升级,主要是资源难找. 下载: (链接: https://pan.baidu.com/s/1eROfQyY 密码: n6ij)

  7. DB2 体系结构 (进程模型)

    DB2 是众多关系型数据库中的一种, 关系型数据库还包括比较火的Oracle,MySQL 实例 数据库 DB2 进程模型 DB2 通过 db2start 命令启动数据库实例,即启动相应的进程和线程,并 ...

  8. DB2 Package Issues and Solution

    Client 从 10.1 升级到11.1之后,而server端的DB 是10.1 版本,当客户执行sql语句时候报错: select * from ebcc.eol_item_info where ...

  9. spring boot快速入门 7: 使用aop处理请求

    样例:登陆拦截(aop简单样例) 第一步:在pom 文件中加入aop依赖 <!-- spring aop --> <dependency> <groupId>org ...

  10. feignClient中修改ribbon的配置

    1.使用@FeignClient注解发现服务 服务提供者的controller: @RestController public class StudentController { @Autowired ...