CF954I Yet Another String Matching Problem 并查集、FFT
传送门
题意:给出两个由小写$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)$
1 #include<bits/stdc++.h> 2 #define eps 1e-2 3 #define ld long double 4 //This code is written by Itst 5 using namespace std; 6 7 inline int read(){ 8 int a = 0; 9 bool f = 0; 10 char c = getchar(); 11 while(c != EOF && !isdigit(c)){ 12 if(c == '-') 13 f = 1; 14 c = getchar(); 15 } 16 while(c != EOF && isdigit(c)){ 17 a = (a << 3) + (a << 1) + (c ^ '0'); 18 c = getchar(); 19 } 20 return f ? -a : a; 21 } 22 23 const int MAXN = 265000; 24 char s1[MAXN] , s2[MAXN]; 25 struct comp{ 26 ld x , y; 27 28 comp(ld _x = 0 , ld _y = 0){ 29 x = _x; 30 y = _y; 31 } 32 33 comp operator +(comp a){ 34 return comp(x + a.x , y + a.y); 35 } 36 37 comp operator -(comp a){ 38 return comp(x - a.x , y - a.y); 39 } 40 41 comp operator *(comp a){ 42 return comp(x * a.x - y * a.y , x * a.y + y * a.x); 43 } 44 }A[MAXN] , B[MAXN]; 45 const ld pi = acos(-1); 46 int fa[MAXN][7] , ans[MAXN] , dir[MAXN] , need; 47 48 inline void FFT(comp* a , int type){ 49 for(int i = 1 ; i < need ; ++i) 50 if(i < dir[i]) 51 swap(a[i] , a[dir[i]]); 52 for(int i = 1 ; i < need ; i <<= 1){ 53 comp wn(cos(pi / i) , type * sin(pi / i)); 54 for(int j = 0 ; j < need ; j += i << 1){ 55 comp w(1 , 0); 56 for(int k = 0 ; k < i ; ++k , w = w * wn){ 57 comp x = a[j + k] , y = a[i + j + k] * w; 58 a[j + k] = x + y; 59 a[i + j + k] = x - y; 60 } 61 } 62 } 63 } 64 65 bool cmp(ld a , ld b){ 66 return a - eps < b && a + eps > b; 67 } 68 69 int find(int dir , int x){ 70 return fa[dir][x] == x ? x : (fa[dir][x] = find(dir , fa[dir][x])); 71 } 72 73 int main(){ 74 #ifndef ONLINE_JUDGE 75 freopen("954I.in" , "r" , stdin); 76 //freopen("954I.out" , "w" , stdout); 77 #endif 78 scanf("%s%s" , s1 , s2); 79 int l1 = strlen(s1) , l2 = strlen(s2); 80 for(int i = 0 ; i < (l2 >> 1) ; ++i) 81 swap(s2[i] , s2[l2 - i - 1]); 82 need = 1; 83 while(need < l1 + l2 - 1) 84 need <<= 1; 85 for(int i = 0 ; i <= l1 - l2 ; ++i) 86 for(int j = 1 ; j <= 6 ; ++j) 87 fa[i][j] = j; 88 for(int i = 1 ; i < need ; ++i) 89 dir[i] = (dir[i >> 1] >> 1) | (i & 1 ? need >> 1 : 0); 90 for(int i = 0 ; i <= 5 ; ++i) 91 for(int j = 0 ; j <= 5 ; ++j) 92 if(i != j){ 93 for(int k = 0 ; k < need ; ++k){ 94 A[k].x = s1[k] == 'a' + i; 95 A[k].y = 0; 96 } 97 for(int k = 0 ; k < need ; ++k){ 98 B[k].x = s2[k] == 'a' + j; 99 B[k].y = 0; 100 } 101 FFT(A , 1); 102 FFT(B , 1); 103 for(int k = 0 ; k < need ; ++k) 104 A[k] = A[k] * B[k]; 105 FFT(A , -1); 106 for(int k = l2 - 1 ; k < l1 ; ++k) 107 if(!cmp(A[k].x , 0)) 108 if(find(k - l2 + 1 , i + 1) != find(k - l2 + 1 , j + 1)){ 109 fa[k - l2 + 1][find(k - l2 + 1 , i + 1)] = find(k - l2 + 1 , j + 1); 110 ++ans[k - l2 + 1]; 111 } 112 } 113 for(int i = 0 ; i <= l1 - l2 ; ++i) 114 printf("%d " , ans[i]); 115 return 0; 116 }
转载于:https://www.cnblogs.com/Itst/p/10040546.html
CF954I Yet Another String Matching Problem 并查集、FFT相关推荐
- CF 954I - Yet Another String Matching Problem FFT 字符串
题意: 给你两个字符串S,T. 对于每个T长度的S子串,你需要求出他们的"距离". 你每次可以将一个字符变成另一个字符,对于两个串都变,距离就是变化次数最小值使得两串相同. 字符集 ...
- CodeForces 828C String Reconstruction(并查集思想)
题意:给你n个串,给你每个串在总串中开始的每个位置,问你最小字典序总串. 思路:显然这道题有很多重复填涂的地方,那么这里的时间花费就会特别高. 我们维护一个并查集fa,用fa[i]记录从第i位置开始第 ...
- string matching(HDU-6629)
Problem Description String matching is a common type of problem in computer science. One string matc ...
- Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) C. String Reconstruction 并查集
C. String Reconstruction 题目连接: http://codeforces.com/contest/828/problem/C Description Ivan had stri ...
- D. The Door Problem 带权并查集
http://codeforces.com/contest/776/problem/D 注意到每扇门都有两个东西和它连接着,那么,如果第i扇门的状态是1,也就是已经打开了,那么连接它的两个按钮的状态应 ...
- String Matching 字符串匹配算法——干货从头放到尾
需要的先验知识:动态规划,有限状态机,搜索算法(就是含有state,action和policy)的模型,java.上面这些不需要知道很细,大概懂这些都是啥就可以读懂本文. 写这篇技术博客的动机是因为做 ...
- 南阳5--Binary String Matching(Kmp)
Binary String Matching 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 Given two strings A and B, whose alpha ...
- CodeForces - 1217F Forced Online Queries Problem(线段树分治+并查集撤销)
题目链接:点击查看 题目大意:给出 nnn 个点,初始时互相不存在连边,需要执行 mmm 次操作,每次操作分为两种类型: 1xy1 \ x \ y1 x y:如果 (x,y)(x,y)(x,y) 之间 ...
- 【CodeForces - 827A】String Reconstruction(并查集合并区间,思维)
题干: Ivan had string s consisting of small English letters. However, his friend Julia decided to make ...
最新文章
- dedecms vdimgck.php,织梦dedecms后台验证码图片不显示解决方案
- Bootstrap 手风琴搭配导航条实现常用菜单栏
- 你根本不懂rebase-使用rebase打造可读的git graph
- css中的单位换算_金蝶ERP入门教程:动态换算率及辅助计量单位的应用
- java程序 启动慢_spring boot 程序启动缓慢的问题
- sass import 小记
- 调用iphone客户端进行授权发微博的方法--使用友盟组件
- php推送mip示例,首页—mip推送软件—首页
- Atitit it软件领域职称评级规定,精深方向。 目录 1. 软件工程师资格证	1 1.1. 法规规范 十大标准,三级五晋制。	1 1.2. 三级制 使用者 原理维修者 制造设计者	1 1.3.
- 有什么低价好用的电容笔推荐?ipad可以用的手写笔分享
- 智能AI文章伪原创工具免费使用注意事项与推荐
- 设置图例legend分行显示
- Spark MLlib系列(二):基于协同过滤的电影推荐系统
- 函数强凸 strong convexity
- PIP 更换国内安装源
- VIF-Benchmark: All infrare and visible image fusion method in one framework
- [bx]与loop指令
- 最近很火的爱心红包教程~可以Biu~发射爱心的微信红包!太有创意啦~
- 有人相爱,有人年少财务自由,有人数据结构都背不出来
- 深信服 2021 面试总结
热门文章
- STM32f103——ILI9341
- GPS NEMA 0183协议
- Datawhale组队-Pandas(下)时序数据(打卡)
- html分类代码查询,html标签元素分类(示例代码)
- python 爬虫是什么_“python爬虫“是什么呢?
- 【Pytorch神经网络实战案例】21 基于Cora数据集实现Multi_Sample Dropout图卷积网络模型的论文分类
- React Portals的使用
- LeetCode 2089. 找出数组排序后的目标下标
- LeetCode 556. 下一个更大元素 III
- LeetCode 220. 存在重复元素 III(lower_bound)