2015 UESTC Training for Search Algorithm String - M - Palindromic String【Manacher回文串】
O(n)的复杂度求回文串:Manacher算法
定义一个回文值,字符串S是K重回文串,当且仅当S是回文串,且其长度为⌊N/2⌋的前缀和长度为⌊N/2⌋的后缀是K−1重回文串
现在给一个2*10^6长度的字符串,求其每个前缀的最大回文值之和。
设dp[i]为长度为i的前缀的最大回文值。
当长度为i的前缀的字符串是回文串的时候,有:dp[i]=dp[i/2]+1
若不是回文串 dp[i]=0
接下来就是怎么样快速的判断回文串了,推荐算法Manacher算法。
Manacher算法先对字符串进行修改 如 aba -> $#a#b#a#
那么该怎么用DP求?
显然一下几点是满足的:
如果某个前缀是回文串,该前缀的末端一定是字符#,(因为第一个符号是#)
故对于不是字符#的位置,它的dp值一定为0
如果最大延伸数组p[i]=i,即向左正好延伸到最左边,那么1~p[i]+i-1一定是一个回文前缀
若第i位是#号 : dp[mx]=dp[i] 其中mx=p[i]+i-1
对于不是#的情况 : dp[mx]=dp[i-1] 其中mx=p[i]+i-1
#include<bits/stdc++.h> #define eps 1e-9 #define FOR(i,j,k) for(int i=j;i<=k;i++) #define MAXN 4000005 #define MAXM 40005 #define INF 0x3fffffff #define PB push_back #define MP make_pair #define X first #define Y second #define lc (k<<1) #define rc ((k<<1)1) using namespace std; typedef long long LL; int i,j,k,n,m,x,y,T,ans,big,cas,num,len; bool flag;int p[MAXN],dp[MAXN]; char str[MAXN],s[MAXN];void kp() {int i;int mx = 0;int id;for(i=n; str[i]!=0; i++)//清除n后边多余的部分str[i] = 0; //没有这一句有问题。。就过不了ural1297,比如数据:ababa abafor(i=1; i<n; i++){if( mx > i )p[i] = min( p[2*id-i], p[id]+id-i );//因为是从左往右扫描的这里i>id, 2*id-i是i关于id的对称点,该对称点在id的左端//p[id]+id是描述中的mx,即id向右延伸的端点位置//显然向右延伸是可能超出mx的,所以要有下边的for循环elsep[i] = 1;for(; str[i+p[i]] == str[i-p[i]]; p[i]++);if( p[i] + i > mx )//更新mx与id,因为mx是向右延伸的最大长度,所以实时更新 {mx = p[i] + i;id = i;}} }void init()//处理字符串 {int i, j, k;str[0] = '$';str[1] = '#';for(i=0; i<n; i++){str[i*2+2] = s[i];str[i*2+3] = '#';}n = n*2+2;s[n] = 0; }int main() {scanf("%s",s);n=strlen(s);init();kp();for (i=2;i<n;i++){if (p[i]==i){int mx=p[i]+i-1;if (str[i]!='#'){dp[mx]=max(dp[mx],dp[i-1]+1);}elsedp[mx]=max(dp[mx],dp[i]+1);}}int sum=0;for (i=0;i<n;i++) sum+=dp[i];printf("%d\n",sum);return 0; }
转载于:https://www.cnblogs.com/zhyfzy/p/4477556.html
2015 UESTC Training for Search Algorithm String - M - Palindromic String【Manacher回文串】相关推荐
- 2016 UESTC Training for Search Algorithm String I - 谭爷剪花布条 KMP
I - 谭爷剪花布条 Time Limit: 3000/100MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit ...
- Manacher's Algorithm 马拉车算法(最长回文串)
这个马拉车算法Manacher's Algorithm是用来查找一个字符串的最长回文子串的线性方法,由一个叫Manacher的人在1975年发明的,这个方法的最大贡献是在于将时间复杂度提升到了线性,这 ...
- HDOJ 5421 Victor and String 回文串自己主动机
假设没有操作1,就是裸的回文串自己主动机...... 能够从头部插入字符的回文串自己主动机,维护两个last点就好了..... 当整个串都是回文串的时候把两个last统一一下 Victor and S ...
- 2019ICPC(徐州) - Colorful String(哈希+二分+动态规划/回文自动机)
题目链接:点击查看 题目大意:给出一个字符串,询问该字符串中的所有回文子串中,各有多少不同的字母 题目分析:这个题题意很简单,在比赛的时候看到字符串第一反应是哈希,哈希+暴力+线段树果不其然的T掉了. ...
- [Leedcode][JAVA][第125题][验证回文串][双指针][String]
[问题描述][简单] 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写.说明:本题中,我们将空字符串定义为有效的回文串.示例 1:输入: "A man, a p ...
- 回文串判断(string类:反转reverse)
2029-Palindromes _easy version Problem Description "回文串"是一个正读和反读都一样的字符串,比如"level" ...
- c++ string 回文串_第33期:上海自来水来自海上,回文字符串验证!
我准备了 1000 本电子书和计算机各领域高清思维导图 100 张,关注后回复[资源],即可获取!更可回复[内推]加入 BAT 内推群! 01.题目示例 见微知著,发现一组数据很有趣,分享给大家.le ...
- 回文串(algorithm)
题目(回文子串的个数) - 中心扩展: 给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目. 回文字符串 是正着读和倒过来读一样的字符串. 子字符串 是字符串中的由连续字符组成的一个序 ...
- HDU-6599 I Love Palindrome String 杭电第二次多校赛(Manacher+回文自动机)
HDU-6599 I Love Palindrome String 杭电第二次多校赛(Manacher+回文自动机) 我的博客:https://acmerszq.cn 原题链接:http://acm. ...
最新文章
- redis设置主从复制-slave Replication--解决报错:(error) READONLY You can't write against a read only slave.
- SAP WMSD集成之Copy WM Quantity – Copy WM qty as delivery qty into delivery
- 【Python 2.x和Python 3.x版本有什么区别】
- HBNIS-crypto
- 『设计模式』反射,反射程序员的快乐!为什么我老是加班?为什么我工资不如他多?原来是我不懂反射!
- STM32F103:二.(2)串口控制LED
- 计算机电源输出定义,电脑电源接口定义图解
- word论文排版和写作05:从word中导出pdf
- React-Router 刷新后报错 or Cannot GET /detail
- 基于功能的差异化战略
- 数的三次方根(二分)
- PAT 1110 区块反转 (25 分) c语言
- php imagejpeg函数,php imagepng()函数有什么用?
- strncpy和strcpy和memcpy
- Android_Butterfly_动画
- 44特征02—— 对角化: 代数重数与几何重数、可对角化的概念
- Angular--小小调色板
- 51单片机~串口通信(讲解+代码)
- CPU缓存一致性协议
- 淘宝网技术发展回顾(六):Java时代:创造技术-Tair