传送门

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

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

求 \(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. iOS开发debug跟release版本NSLog屏蔽方法

    简单介绍以下几个宏: 1) __VA_ARGS__ 是一个可变参数的宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持).宏前面加上##的作用在于,当可变参 ...

  2. Java操作数据库实现"增删改查"

    本文主要讲解JDBC操作数据库    主要实现对MySql数据库的"增删改查" 综合概述: JDBC的常用类和接口 一   DriverManager类 DriverManage类 ...

  3. Oracle 11g

    Oracle 11g 第一章  Oracle 11g数据库简介 1.1  认识Oracle11g Oracle 11g是Oracle 数据库最新的版本,目前已经被企业广泛的应用. 1.2  Oracl ...

  4. Python unittest第一篇:基础入门+命令行编译

    unittest单元测试框架最初受JUnit启发,与其他语言的主要单元测试框架具有相似的风格. 它支持测试自动化,支持开启或关闭某个测试,支持结合测试.另外它可以生成各个单元测试的报告.为了实现以上功 ...

  5. SpringMVC初写(一)SpringMVC的配置方式

    1.Spring概述a)SpringMVC是什么?SpringMVC是Spring框架内置的MVC实现.SpringMVC就是一个Spring内置的MVC子框架MVC:Model-View-Contr ...

  6. Linux快速查看某条命令的版本和存放的位置(ls -l `which mvn`)

    输入: ls -l `which mvn` 如图:

  7. 异常捕获设置HTTPStatus

    第一步:创建一个异常类 package com.payease.exception; /** * @Created By liuxiaoming * @CreateTime 2017/12/12 下午 ...

  8. eclipse中提示js或者JQuery代码

    当你在eclipse中的JSP中写JavaScript或者JQuery代码的时候,eclipse是不会自动提示的,所以你需要在eclipse中安装一下插件,该插件的名字叫:Spket IDE,它可以作 ...

  9. 西蒙布朗-C4模型

    关于 C4 模型的一些解释 C4 模型是来自 software architecture for developers 一书的定义,指的是 Context 上下文场景.Container 容器.Com ...

  10. nginx 配置静态资源路径(url不同于static path)

    目的         用nginx做静态资源代理可以减少请求对后台服务器的压力,使响应更加迅速. 配置        情景一           url : 127.0.0.1:8000/images ...