传送门

题意:给出两个由小写$a$到$f$组成的字符串$S$和$T$($|S| \geq |T|$),给出变换$c1\,c2$表示将两个字符串中所有$c1$字符变为$c2$,求$S$的每一个长度为$T$的子串与$T$做变换使得两个字符串相等的最小变换次数。$1 \leq |T| \leq |S| \leq 1.25 \times 10^5$


弱化版:CF939D

PS:默认字符串开头是第$0$位

我们同样考虑通过CF939D的那种方法解决这个问题。考虑到这道题的字符集大小只有$6$,也就是说本质不同的边的条数只有$30$条。我们可以考虑枚举$S$中的字符$x$与$T$中的字符$y$的连边情况。将$T$反序后,将$S$中的字符$x$对应为$1$,T中的字符$y$也对应为$1$,其他的都对应为$0$。然后对这两个对应的数组做$FFT$,这样得到的结果的第$x$位如果不为$0$,意味着$S$的以第$x - |T| + 1$位为开头的子串中存在$x$到$y$的连边(如果不是很理解可以自己画图qwq)。然后对每一个$S$的子串开并查集维护就可以了。复杂度$O(30nlogn)$

 #include<bits/stdc++.h>
 #define eps 1e-2
 #define ld long double
 //This code is written by Itst
 using namespace std;

 inline int read(){
     ;
     ;
     char c = getchar();
     while(c != EOF && !isdigit(c)){
         if(c == '-')
             f = ;
         c = getchar();
     }
     while(c != EOF && isdigit(c)){
         a = (a << ) + (a << ) + (c ^ ');
         c = getchar();
     }
     return f ? -a : a;
 }

 ;
 char s1[MAXN] , s2[MAXN];
 struct comp{
     ld x , y;

     comp(ld _x =  , ld _y = ){
         x = _x;
         y = _y;
     }

     comp operator +(comp a){
         return comp(x + a.x , y + a.y);
     }

     comp operator -(comp a){
         return comp(x - a.x , y - a.y);
     }

     comp operator *(comp a){
         return comp(x * a.x - y * a.y , x * a.y + y * a.x);
     }
 }A[MAXN] , B[MAXN];
 );
 ] , ans[MAXN] , dir[MAXN] , need;

 inline void FFT(comp* a , int type){
      ; i < need ; ++i)
         if(i < dir[i])
             swap(a[i] , a[dir[i]]);
      ; i < need ; i <<= ){
         comp wn(cos(pi / i) , type * sin(pi / i));
          ; j < need ; j += i << ){
             comp w( , );
              ; k < i ; ++k , w = w * wn){
                 comp x = a[j + k] , y = a[i + j + k] * w;
                 a[j + k] = x + y;
                 a[i + j + k] = x - y;
             }
         }
     }
 }

 bool cmp(ld a , ld b){
     return a - eps < b && a + eps > b;
 }

 int find(int dir , int x){
     return fa[dir][x] == x ? x : (fa[dir][x] = find(dir , fa[dir][x]));
 }

 int main(){
 #ifndef ONLINE_JUDGE
     freopen("954I.in" , "r" , stdin);
     //freopen("954I.out" , "w" , stdout);
 #endif
     scanf("%s%s" , s1 , s2);
     int l1 = strlen(s1) , l2 = strlen(s2);
      ; i < (l2 >> ) ; ++i)
         swap(s2[i] , s2[l2 - i - ]);
     need = ;
     )
         need <<= ;
      ; i <= l1 - l2 ; ++i)
          ; j <=  ; ++j)
             fa[i][j] = j;
      ; i < need ; ++i)
         dir[i] = (dir[i >> ] >> ) | (i &  ? need >>  : );
      ; i <=  ; ++i)
          ; j <=  ; ++j)
             if(i != j){
                  ; k < need ; ++k){
                     A[k].x = s1[k] == 'a' + i;
                     A[k].y = ;
                 }
                  ; k < need ; ++k){
                     B[k].x = s2[k] == 'a' + j;
                     B[k].y = ;
                 }
                 FFT(A , );
                 FFT(B , );
                  ; k < need ; ++k)
                     A[k] = A[k] * B[k];
                 FFT(A , -);
                  ; k < l1 ; ++k)
                     ))
                          , i + ) != find(k - l2 +  , j + )){
                             fa[k - l2 + ][find(k - l2 +  , i + )] = find(k - l2 +  , j + );
                             ++ans[k - l2 + ];
                         }
             }
      ; i <= l1 - l2 ; ++i)
         printf("%d " , ans[i]);
     ;
 }

CF954I Yet Another String Matching Problem 并查集、FFT的更多相关文章

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

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

  2. CF954I Yet Another String Matching Problem

    传送门 每次操作可以把两个字符串中所有同一种字符变成另外一种 定义两个长度相等的字符串之间的距离为:使两个字符串相等所需要操作的次数的最小值 求 \(s\) 中每一个长度为 \(|t|\) 的连续子串 ...

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

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

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

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

  5. 954I Yet Another String Matching Problem

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

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

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

  7. A simple problem(并查集判环)

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2497 题意:给定一些点和边的关系,判断S点是否 ...

  8. String Reconstruction (并查集)

    并查集维护和我这个位置的字母连续的已经被填充的字母能到达的最右边的第一个还没有填充的位置,然后把这个位置填上应该填的东西,然后把这个位置和下一个位置连接起来,如果下一个位置还没有填,我就会把下一个位置 ...

  9. CodeForces 828C String Reconstruction(并查集思想)

    题意:给你n个串,给你每个串在总串中开始的每个位置,问你最小字典序总串. 思路:显然这道题有很多重复填涂的地方,那么这里的时间花费就会特别高. 我们维护一个并查集fa,用fa[i]记录从第i位置开始第 ...

随机推荐

  1. easyUI combobox combotree 模糊查询,带上下键选择功能,待完善。。。。

    /2017年4月9日 11:52:36 /** * combobox和combotree模糊查询 * combotree 结果带两级父节点(手动设置数量) * 键盘上下键选择叶子节点 * 键盘回车键设 ...

  2. Ansible--原理

    什么是Ansible Ansible是一种IT自动化运维工具,它可以配置系统,部署软件以及协调更高级的IT任务,例如持续部署或者是零停机滚动更新Ansible是新出现的自动化运维工具,基于Python ...

  3. Linux 操作系统下为网卡配置ip

    Linux操作系统下为网卡配置ip by:授客 QQ:1033553122 1.   Linux单一网卡设置多IP的配置方法 在Linux下网卡接口逻辑名被称为eth0,eth1,eth2,..... ...

  4. node中__dirname、__filename、process.cwd()、process.chdir()表示的路径

    直接上结论:__dirname 表示当前文件所在的目录的绝对路径__filename 表示当前文件的绝对路径module.filename ==== __filename 等价process.cwd( ...

  5. 给 Linux 系统“减肥”,系统垃圾清理_系统安装与配置管理_Linux Today - Google Chrome

    给 Linux 系统"减肥",系统垃圾清理  2013/10/16  linux  系统安装与配置管理  评论  15,555 Linux 计算机安装后,在我们不断的使用过程中,因 ...

  6. trap命令的实战用法

    trap命令: trap命令是专用于捕捉信号的.比如像ctrl+c发送给终端的中断信号等等.在捕捉到信号之后,可以进行一系列的操作. 用法:trap  'COMMAND' INT COMMAND表示t ...

  7. cpio的用法

    cpio 这个命令挺有趣的,因为 cpio 可以备份任何东西,包括装置设备文件.不过 cpio 有个大问题, 那就是 cpio 不会主动的去找文件来备份!啊!那怎办?所以罗,一般来说, cpio 得要 ...

  8. 解决pycharm下代码报错的问题

    file-----settings------project:Pythonstudy------project structure-----选择要导入的文件并点击OK

  9. 串口-CreateFile的使用

    在32位的windows系统中,串口和其他通信设备是作为文件处理的.对串口的操作和对文件的操作是完全一样的.通信以调用CreateFile()开始. 函数原型如下: HANDLE CreateFile ...

  10. Linux 小知识翻译 - 「环境变量」

    这次,谈谈关于「环境变量」的话题. 所谓变量,就是在程序中设置的,相当于在内存中准备的「一个用来存放数据的小箱子」. 即,程序通过变量来保存值,通过变量保存的内容来进行各式各样的计算处理. 「环境变量 ...