zoj4110 Strings in the Pocket(manacher)
传送:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=6012
题意:给定两个串$S$和$T$,可以翻转$S$串中的任意一个子段,得到$T$。问,可以翻转的方案书有多少?
数据范围:多组数据。$1\leq|S|\leq2\times10^5$,$\sum|S|\leq2\times10^7$。
分析:很明显需要分类讨论$S$与$T$比较的各种情况。
首先需要判断$S$串从左和从右找到与$T$开始不同的位置。
- $S$不可以翻转成$T$:就是指$S$串中不同的那一段不可以通过翻转得到$T$,方案数为0。
- $S$与$T$不同的“中间”那一段可以通过翻转得到对应$T$的那一段。这个时候需要向外扩展判断最长可以扩展到的位置。
- $S$与$T$完全相同,这个时候就需要通过manacher来求解整个串内回文子串的个数。
代码:
- 不分奇偶讨论的manacher
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=2e6+10; 5 char S[maxn],T[maxn],s[maxn*2]; 6 int p[maxn*2],len; 7 int init(){ 8 s[0]=s[1]='#'; 9 for (int i=0;i<len;i++){ 10 s[i*2+2]=S[i]; 11 s[i*2+3]='#'; 12 } 13 len=len*2+2; 14 s[len]=0; 15 } 16 void manacher(){ 17 int id,mx=0; 18 for (int i=1;i<len;i++){ 19 if(i<mx) p[i]=min(p[(id<<1)-i],p[id]+id-i); 20 else p[i]=1; 21 while (s[i-p[i]]==s[i+p[i]]) p[i]++; 22 if (mx<i+p[i]){ 23 id=i;mx=i+p[i]; 24 } 25 } 26 } 27 int main(){ 28 int t; scanf("%d",&t); 29 while (t--){ 30 scanf("%s",S); 31 scanf("%s",T); 32 len=strlen(S); 33 int l=0,r=len-1; ll ans=0; 34 while (S[l]==T[l] && l<len) l++; 35 while (S[r]==T[r] && r>=0) r--; 36 if (l==r){printf("0\n"); continue;} 37 if (l<len){ 38 ans=1; 39 for (int i=l;i<=r;i++) 40 if (S[i]!=T[l+r-i]){ 41 ans=0; break; 42 } 43 if (ans){ 44 ans=1; 45 l--;r++; 46 while (l>=0 && r<len && S[l]==T[r] && S[r]==T[l]){ 47 l--;r++;ans++; 48 } 49 } 50 printf("%d\n",ans); 51 } 52 else{ 53 init(); 54 manacher(); ans=1; 55 for (int i=0;i<len;i++) ans+=(p[i]/2); 56 printf("%lld\n",ans-1); 57 } 58 } 59 return 0; 60 }
2.分奇偶讨论的manacher
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=2e6+10; 5 char S[maxn],T[maxn]; 6 int odd[maxn],eve[maxn],len; 7 ll manacher(){ 8 int l=-1,r=-1,x; 9 ll ans=0; 10 for(int i=0;i<len;i++) 11 { 12 if (i>r) x=1; 13 else x=min(odd[l+r-i],r-i); 14 while (i-x>=0 && i+x<len && S[i-x]==S[i+x]) x++; 15 odd[i]=x; 16 ans+=x; 17 if (i+x-1>r) {r=i+x-1;l=i-x+1;} 18 } 19 l=r=-1; 20 for(int i=0;i<len;i++) 21 { 22 if(i>r) x=0; 23 else x=min(eve[l+r-i+1],r-i+1); 24 while (i-x-1>=0 && i+x<len && S[i-x-1]==S[i+x]) x++; 25 eve[i]=x; 26 ans+=x; 27 if (i+x>=r) {l=i-x;r=i+x-1;} 28 } 29 return ans; 30 } 31 int main(){ 32 int t; scanf("%d",&t); 33 while (t--){ 34 scanf("%s",S); 35 scanf("%s",T); 36 len=strlen(S); 37 int l=0,r=len-1; ll ans=0; 38 while (S[l]==T[l] && l<len) l++; 39 while (S[r]==T[r] && r>=0) r--; 40 if (l==r){printf("0\n"); continue;} 41 if (l<len){ 42 ans=1; 43 for (int i=l;i<=r;i++) 44 if (S[i]!=T[l+r-i]){ 45 ans=0; break; 46 } 47 if (ans){ 48 ans=1; 49 l--;r++; 50 while (l>=0 && r<len && S[l]==T[r] && S[r]==T[l]){ 51 l--;r++;ans++; 52 } 53 } 54 printf("%d\n",ans); 55 } 56 else{ 57 ans=manacher(); 58 printf("%lld\n",ans); 59 } 60 } 61 return 0; 62 }
转载于:https://www.cnblogs.com/changer-qyz/p/10792437.html
zoj4110 Strings in the Pocket(manacher)相关推荐
- 最长回文字符串——马拉车(Manacher)算法
最长回文字符串--马拉车(Manacher)算法 说来惭愧,都快要毕业了才写第一篇博客... 回文串 回文串呢,就是在一个字符串中,左半部分和右半部分是镜像对称的字符串,比如abcba,就是一个已c为 ...
- 算法练习day18——190409(Manacher)
1.Manacher算法 一个串中,找到最长的回文子串. 1.1 暴力解决 得解决长度为奇数的回文和长度为偶数的回文. 1.1.1 奇回文 i位置自己肯定构成回文:长度为1 i+1位置和i-1位置相不 ...
- 小G的项链(Manacher)
我看网上也没有写这个题的,顺便写一下(可能是大佬都觉得太简单了 ) 链接:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K 64bit IO ...
- 马拉车(manacher)算法——最长回文(hdu3068)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3068 题目描述: Problem Description 给出一个只由小写英文字符a,b,c...y ...
- 彻底搞懂马拉车(Manacher)
Manacher算法,又叫"马拉车",它可以在时间复杂度和空间复杂度都是O(n)的情况下,求出一个字符串的最长回文串长度. 回文串的基本解法 以每一个点为中心对称点,每次保留最长回 ...
- 马拉车(manacher)算法
本篇博客基于这篇博客的理解. 马拉车可以在线性时间内找到字符串的最大回文子串. 先来说说它是如何工作的. 其实本质上马拉车算是一个很优美的暴力算法,它从头到尾遍历一遍字符串的每一个元素,然后把当前遍历 ...
- KMP BFPRT 马拉车(Manacher)
目录 1.KMP: Ⅰ.某个字符的"指标" ⅠⅠ.KMP的使用方法: ⅠⅠⅠ.理由1: ⅠⅤ.理由2: Ⅴ."指标的获取": ⅤⅠ.代码部分: 2.BFPRT( ...
- 马拉车算法(manacher)求最长回文子串
关于回文字符串的概念大家可以大致去搜索一下,这里不赘述. 一.解题思路 当前字符串 最长回文子串: 思路实际上很简单,就是遍历每一个元素,然后分别以这个元素为中心,向两边扩展,比如说现在i = 4,那 ...
- 【2019浙江省赛 - K 】Strings in the Pocket(马拉车,思维)
题干: BaoBao has just found two strings and in his left pocket, where indicates the -th character i ...
最新文章
- 支付宝app支付总结
- RTlinux3.2安装
- 检查Android应用程序是否在后台运行
- 一次微服务与IoT的深度探秘与实战
- Android 4.4沉浸式状态栏的实现
- Android在Shell环境下运行Linux命令
- Ubuntu18.04安装Gaussian16和GaussView 6
- python__和_区别_【Python】对_和__差别的理解
- sparkshelljarlib_spark-submit 应用程序第三方jar文件
- 线性瘤是良性吗_良性聚会:露营者如何构建开放源代码工具来解决时区
- mysql定义和调用存储过程
- gcc -o sqlite3 shell.c sqlite3.c -ldl -lpthread
- 使用自定义手势处理器-陈鹏
- VS2013 MFC 中DLL链接库断点不能命中的解决方案总结
- HUSTOJ(2019)在线判题系统的搭建
- Cesium加载OSGB数据
- linux服务器安装cuda,在Linux下安装Cuda5
- AI安全技术总结与展望
- Windows相关产品密钥
- 品荔枝赏文化,美丽乡村不一样的嘉年华
热门文章
- html资源加载,如何加载文件资源 (HTML)
- c#结合emgucv进行人脸检测_人脸识别与测温结合在办公场景有哪些应用?
- layui fixbar 返回顶部_FANUC 数控系统机床返回参考点功能的应用研究
- seaborn系列 (17) | 回归模型图lmplot()
- 5笔涂出一只3D猫咪模型,可跑可跳无需手动绑定骨骼,新鬼畜素材get丨浙大开源...
- 72岁奶奶在抖音教物理火了,百万粉丝追更,网友:小时候要有这种老师就好了...
- 速来!亚马逊云科技AI盛会开源专场吹响集结号
- Nature今年首次撤稿给了微软:研究团队成员自曝删改不利数据,量子计算重大进展是假的...
- 3个可以写进简历的京东AI NLP项目实战,走完这五步就是Top算法工程师
- 斩获23项冠军,日均调用破万亿!百度交出年度AI成绩单:语音语言领衔技术突破,国产自研成大趋势...