传送门

分析

我们先考虑暴力如何计算

对于S的子串SS,如果它有位置i使得SS[i] != T[i]那么我们就将两个字符之间用并查集连边

最后答案很明显就是并查集中所有边的个数

于是我们可以发现对于S[i] != T[j]衣服那个会在S的第i-j个子串连边

我们通过观察可以发现i - j = i - (m - j) +m

这是一个卷积的形式

于是我们枚举S和T中考虑的是那种字符然后卷积判断连边关系

最后进行之前说的并查集即可

代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<string>
  5. #include<algorithm>
  6. #include<cctype>
  7. #include<cmath>
  8. #include<cstdlib>
  9. #include<queue>
  10. #include<ctime>
  11. #include<vector>
  12. #include<set>
  13. #include<map>
  14. #include<stack>
  15. using namespace std;
  16. const int mod = ;
  17. const int g = ;
  18. int fa[][];
  19. char s[],ot[],t[];
  20. int n,m,r[],len,N,a[],b[],G,ans[];
  21. inline int pw(int x,int p){
  22. int res=;
  23. while(p){
  24. if(p&)res=1ll*res*x%mod;
  25. x=1ll*x*x%mod;
  26. p>>=;
  27. }
  28. return res;
  29. }
  30. inline void ntt(int a[],int f){
  31. register int i,j,k;
  32. int now;
  33. for(i=;i<n;++i)
  34. if(i<r[i])swap(a[i],a[r[i]]);
  35. for(i=;i<n;i<<=){
  36. if(f==)now=g;
  37. else now=G;
  38. int wn=pw(now,(mod-)/(i<<));
  39. for(j=;j<n;j+=(i<<)){
  40. int w=,x,y;
  41. for(k=;k<i;++k,w=1ll*w*wn%mod){
  42. x=a[j+k],y=1ll*a[i+j+k]*w%mod;
  43. a[j+k]=(x+y)%mod,a[i+j+k]=(x+mod-y)%mod;
  44. }
  45. }
  46. }
  47. }
  48. inline int sf(int wh,int x){return fa[wh][x]==x?x:fa[wh][x]=sf(wh,fa[wh][x]);}
  49. signed main(){
  50. register int i,j,k;
  51. int on,om;
  52. G=pw(g,mod-);
  53. scanf("%s",s);
  54. scanf("%s",ot);
  55. n=strlen(s),m=strlen(ot);
  56. for(i=;i<m;++i)t[i]=ot[m-i-];
  57. n--,m--;
  58. on=n,om=m;
  59. m+=n;
  60. for(n=;n<=m;n<<=)len++;
  61. for(i=;i<n;++i)r[i]=((r[i>>]>>)|((i&)<<(len-)));
  62. for(i=om;i<=on;++i)
  63. for(j=;j<;++j)fa[i-om][j]=j;
  64. for(i=;i<;++i)
  65. for(j=;j<;++j){
  66. if(i==j)continue;
  67. memset(a,,sizeof(a));
  68. memset(b,,sizeof(b));
  69. for(k=;k<=on;++k)a[k]=((s[k]-'a')==i);
  70. for(k=;k<=om;++k)b[k]=((t[k]-'a')==j);
  71. ntt(a,),ntt(b,);
  72. for(k=;k<n;k++)a[k]=1ll*a[k]*b[k]%mod;
  73. ntt(a,-);
  74. int inv=pw(n,mod-);
  75. for(k=;k<n;++k)a[k]=1ll*a[k]*inv%mod;
  76. for(k=om;k<=on;++k)if(a[k]){
  77. int x=sf(k-om,i),y=sf(k-om,j);
  78. if(x==y)continue;
  79. ans[k-om]++;
  80. fa[k-om][x]=y;
  81. }
  82. }
  83. for(i=om;i<=on;++i)printf("%d ",ans[i-om]);
  84. return ;
  85. }

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

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

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

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

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

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

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

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

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

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

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

  6. CF954I Yet Another String Matching Problem

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

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

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

  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. linux(7)

    第十七单元 Samba服务 [本节内容]1. 掌握samba的功能: samba是一个网络服务器,用于Linux和Windows之间共享文件.2. 掌握samba服务的启动.停止.重启service ...

  2. Ninject Lazy Load

    namespace LayzyLoadTest { [TestClass] public class UnitTest1 { private IKernel InitKernel() { Ninjec ...

  3. 双口RAM,值得研究

    在FPGA设计过程中,使用好双口RAM,也是提高效率的一种方法. 官方将双口RAM分为简单双口RAM和真双口RAM. 简单双口RAM只有一个写端口,一个读端口. 真双口RAM分别有两个写端口和两个读端 ...

  4. ACM-世界岛旅行

    [问题描述] 某旅游公司组团去迪拜世界岛旅游.世界岛由n个岛屿组成,岛屿序号为1-n,这些岛屿都直接或间接相连.岛屿之间用桥梁连接.现从1号岛屿开始游览,并约定按如下方式游览: 1) 每游览完一个岛屿 ...

  5. 浅谈使用 PHP 进行手机 APP 开发(API 接口开发)

    做过 API 的人应该了解,其实开发 API 比开发 WEB 更简洁,但可能逻辑更复杂,因为 API 其实就是数据输出,不用呈现页面,所以也就不存在 MVC(API 只有 M 和 C),那么我们来探讨 ...

  6. Linux 发展史

    操作系统 英文名称为operating system,简称os,是应用程序运行及用户操作必备的基础环境支撑,计算机系统的核心,作用是管理和控制计算机系统中的硬件和软件资源 操作系统就是处于用户与计算机 ...

  7. python学习笔记(十一):网络编程

    一.python操作网络,也就是打开一个网站,或者请求一个http接口,使用urllib模块. urllib模块是一个标准模块,直接import urllib即可,在python3里面只有urllib ...

  8. sgdisk基本用法

    简介 sgdisk是Linux下操作GPT分区的工具,就像fdisk是操作MBR分区的工具.关于GPT和MBR的区别请参考: http://www.anchor.com.au/blog/2012/10 ...

  9. Masking operations

    Using a mask, multiple bits in a nibble, byte, words can be set either on, off or inverted from on t ...

  10. 第二章:Android Studio概述(二)[学习Android Studio汉化教程]

    The Main Menu Bar 主菜单栏  主菜单栏位于Android Studio的最上面,你几乎可以利用主菜单和其子菜单来执行任何操作.不像Android Studio中其他的一些菜单,主菜单 ...