传送门

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

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

求 \(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关于代码风格问题

    cocoapods管理第三方库,详见cocoapods安装及使用 OC代码风格需要规范,所有第三方依赖需要用cocoapods管理.代码风格需要: 1. pod 'CodeFormatter', :g ...

  2. iOS应用发布中的一些细节

    iOS应用发布中的一些细节 前言 这几天最大的新闻我想就是巴黎恐怖袭击了,诶,博主每年跨年都那么虔诚地许下“希望世界和平”的愿望,想不到每年都无法实现,维护世界和平这么难,博主真是有心无力啊,其实芸芸 ...

  3. 【性能测试】:oracle数据库的监控方式

    一,[前提]:登陆操作系统后,需要切换到SQLPLUS的命令行模式:sqlplus / as sysdba 二,[监控步骤]:开始时执行一次:SQL>exec DBMS_WORKLOAD_REP ...

  4. 20190417 CentOS 7下安装ActiveMQ

    前言 用VMware安装CentOS 7.6,创建一个新的用户lihailin9073,并使用这个用户登陆CentOS系统 安装和启动 登陆ActivieMQ官网http://activemq.apa ...

  5. kubernetes 与LVM的结合

    本文主要介绍k8s与LVM结合使用的场景,在原生的k8s中对于本地存储提供了hostPath与emptyDir两种volme,hostPath是直接将文件存储在本地主机上,存在的问题是无法进行quot ...

  6. centos 7编译安装Python3.6.1

    1.准备必要的库文件 yum install -y gcc zlib-devel openssl-devel sqlite-devel 2.进入源代码包 ./configure prefix=/usr ...

  7. Java多线程(二)同步与等待唤醒

     1:数据安全问题 1.1:什么情况下会出现数据安全问题? 多个线程对同一个资源进行操作,并且操作资源的语句有多条.那么这个时候这些语句因为cpu的随机性,有可能被多个线程分开执行.导致数据安全问题. ...

  8. bash切割文件

    split -l 100 ./x01.txt -d -a 3 --additional-suffix=.txt 将 x01.txt文件,-l 100 按照每个100行,  -d 以数字累加, -a 3 ...

  9. PHP之string之addslashes()函数使用

    addslashes (PHP 4, PHP 5, PHP 7) addslashes - Quote string with slashes addslashes - 使用反斜线引用字符串 Desc ...

  10. PHP之mb_check_encoding使用

    mb_check_encoding (PHP 4 >= 4.4.3, PHP 5 >= 5.1.3, PHP 7) mb_check_encoding - Check if the str ...