传送门

题意:给出两个由小写$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. SuperMap iObject .NET开发完成后私有部署,打包安装

    转载自:http://blog.csdn.net/supermapsupport/article/details/53319800 作者:皇皇 SuperMap iObjict .NET组件开发结束后 ...

  2. [OTA] 系统加密后Recovery是如何读取OTA升级包的

    目前很多Android手机采用的FUSE方案,也就是内部SD卡不单独占用一个文件系统而实际上占用的是userdata的空间. 当系统加密后,解密需要VOLD的参于.而在Recovery模式下,是没有V ...

  3. [20180718]拷贝数据文件从dg库.txt

    [20180718]拷贝数据文件从dg库.txt 1.测试环境:SCOTT@book> @ ver1PORT_STRING                    VERSION        B ...

  4. C# MD5 加密

    public static string MD5Encrypt(string clearText) { string result = string.Empty; byte[] byteArray = ...

  5. 通过日志过滤的方法,统计每天内容详情页面的PV数

    1.目的: 每天凌晨0点1分统计用户点击进入内容详情页的次数,对内容点击量形成榜单. 2.分析: A./data/log/epg.access.log日志实时打印用户访问页面的日志,并且每天凌晨0点会 ...

  6. 监控.net 网站 Glimpse

    使用Nuget 安装Glimpse 安装好后,config会默认添加几个节点 安装好之后 只需要浏览器输入  网站/Glimpse.axd 再次进入网站 就可以查看(ajax sql session ...

  7. kafka集群管理工具kafka-manager部署安装

    一.kafka-manager 简介 为了简化开发者和服务工程师维护Kafka集群的工作,yahoo构建了一个叫做Kafka管理器的基于Web工具,叫做 Kafka Manager.这个管理工具可以很 ...

  8. P1019 单词接龙

    单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一 ...

  9. python中的轻量级定时任务调度库:schedule

    提到定时任务调度的时候,相信很多人会想到芹菜celery,要么就写个脚本塞到crontab中.不过,一个小的定时脚本,要用celery的话太“重”了.所以,我找到了一个轻量级的定时任务调度的库:sch ...

  10. java通过传入的日期,获取所在周的周一至周日

    public static void main(String[] args) { try { SimpleDateFormat sdf=new SimpleDateFormat("yyyy- ...