传送门

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

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

求 \(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. sqlplus登录远程数据库与数据导出

    一.登录 1.cmd中输入sqlplus /nolog 2.链接数据库,root是用户名,root123是密码,ORCL是数据库名.conn root/root123@192.168.1.27:152 ...

  2. 任务调度SpringTask

    一.什么是任务调度 在企业级应用中,经常会制定一些“计划任务”,即在某个时间点做某件事情,核心是以时间为关注点,即在一个特定的时间点,系统执行指定的一个操作.常见的任务调度框架有Quartz和Spri ...

  3. appium安装与部署

    前提: ①:appium属于C/S架构,代码写在Client端 ②:本章所说的部署讲的是Android设备下的Appium安装与部署 ③:Appium Client的环境是针对python3的 App ...

  4. 杨辉三角-python

    # -*- coding: utf-8 -*- def triangles(): yield [1] # n = 0 第一行 yield [1, 1] # n = 1 第二行 b, n, old = ...

  5. scrapyd的安装

    .安装 pip3 install scrapyd 二.配置 安装完毕之后,需要新建一个配置文件/etc/scrapyd/scrapyd.conf,Scrapyd在运行的时候会读取此配置文件. 在Scr ...

  6. 织梦dede解决“更新数据库archives表时出错"方法

    登陆dedecms网站管理后台,选择执行 sql命令工具,将下列命令执复制进去并执行多行执行,该问题就可以解决. alter table `idea_archives` ADD `voteid` me ...

  7. 把TextView中的文字添加阴影效果及Style的使用 mono版

    android:shadowColor 阴影颜色 android:shadowDx 阴影的水平偏移量 android:shadowDy 阴影的垂直偏移量 android:shadowRadius 阴影 ...

  8. 原创:centos7.1下 ZooKeeper 集群安装配置+Python实战范例

    centos7.1下 ZooKeeper 集群安装配置+Python实战范例 下载:http://apache.fayea.com/zookeeper/zookeeper-3.4.9/zookeepe ...

  9. PHP操作sqlserver乱码解决

    将捕获的参数编码转换为GB2312即可 function ($string){ returen iconv("UFT-8","GB2312//IGNORE",$ ...

  10. h2数据库的简单使用

    1.登录H2数据库的WebConsole控制台 2.设置数据库连接 3.连接测试通过之后,点击[连接]按钮,登录到test数据库的webConsole 4.创建表 复制H2数据库提供的样例SQL脚本, ...