Manacher算法求回文半径
这篇讲的比较好,准备一个模板,做题的时候用。
- void manacher()
- {
- int mx = , id = ;
- for (int i = ; i <= n; i++)
- {
- if (mx > i)
- p[i] = min(p[id * - i], mx - i);
- else
- p[i] = ;
- while (a[i + p[i]] == a[i - p[i]])
- p[i]++;
- if (mx < p[i] + i)
- {
- mx = p[i] + i;
- id = i;
- }
- }
- }
这个初始化的时候是从1开始的
- for (int i = ; i <= n; i++)
- {
- a[i * - ] = str[i];
- a[i * ] = -;
- }
其中p表示回文半径,str是原串,a表示添加字符之后的串
两个例题:
- #include <cstdio>
- #include <iostream>
- #include <cstring>
- #include <cmath>
- #include <cstdlib>
- #include <algorithm>
- using namespace std;
- typedef long long LL;
- const int maxn = ;
- char str[maxn], a[maxn<<];
- int p[maxn<<], L[maxn<<], R[maxn<<];
- int n;
- void manacher()
- {
- int mx = , id = ;
- for (int i = ; i <= n; i++)
- {
- if (mx > i)
- p[i] = min(p[id * - i], mx - i);
- else
- p[i] = ;
- while (a[i + p[i]] == a[i - p[i]])
- p[i]++;
- if (mx < p[i] + i)
- {
- mx = p[i] + i;
- id = i;
- }
- }
- }
- bool solve()
- {
- for (int i = ; i <= L[]; i++)
- {
- for (int j = ; j <= R[]; j++)
- {
- int l = L[i] + ;
- int r = R[j] - ;
- if (r - l <= )
- continue;
- int mid = (l + r) / ;
- if (p[mid] >= r - mid + )
- return true;
- }
- }
- return false;
- }
- int main()
- {
- int T;
- scanf("%d", &T);
- while (T--)
- {
- scanf("%s", str + );
- n = strlen(str + );
- for (int i = ; i <= n; i++)
- {
- a[i * - ] = str[i];
- a[i * ] = '#';
- }
- n = n * - ;
- a[] = '$';
- a[n + ] = '@';
- manacher();
- memset(L, , sizeof(L));
- memset(R, , sizeof(R));
- for (int i = ; i <= n; i++)
- {
- int l = i - p[i] + ;
- int r = i + p[i] - ;
- if (l == )
- L[++L[]] = r;
- if (r == n)
- R[++R[]] = l;
- }
- if (solve())
- puts("Yes");
- else
- puts("No");
- }
- return ;
- }
- #include <cstdio>
- #include <iostream>
- #include <cstring>
- #include <cmath>
- #include <cstdlib>
- #include <algorithm>
- using namespace std;
- typedef long long LL;
- const int maxn = ;
- int str[maxn], a[maxn<<];
- int p[maxn<<];
- int n;
- void manacher()
- {
- int mx = , id = ;
- for (int i = ; i <= n; i++)
- {
- if (mx > i)
- p[i] = min(p[id * - i], mx - i);
- else
- p[i] = ;
- while (a[i + p[i]] == a[i - p[i]])
- p[i]++;
- if (mx < p[i] + i)
- {
- mx = p[i] + i;
- id = i;
- }
- }
- }
- void print()
- {
- for (int i = ; i <= n; i++)
- printf("%d ", p[i]);
- }
- int main()
- {
- int T;
- int kase = ;
- scanf("%d", &T);
- while (T--)
- {
- scanf("%d", &n);
- for (int i = ; i <= n; i++)
- scanf("%d", &str[i]);
- for (int i = ; i <= n; i++)
- {
- a[i * - ] = str[i];
- a[i * ] = -;
- }
- int m = n;
- n = n * - ;
- a[] = -;
- a[n + ] = -;
- manacher();
- int ans = ;
- for (int i = ; i <= n; i += )
- p[i] /= ;
- for (int i = ; i <= n; i += )
- {
- if (p[i] * < ans)
- continue;
- for (int j = p[i]; j * >= ans; j--)
- {
- if (p[i + j * ] >= j)
- {
- ans = max(ans, j * );
- break;
- }
- }
- }
- printf("Case #%d: %d\n", ++kase, ans);
- }
- return ;
- }
Manacher算法求回文半径的更多相关文章
- HDU 5371(2015多校7)-Hotaru's problem(Manacher算法求回文串)
题目地址:HDU 5371 题意:给你一个具有n个元素的整数序列,问你是否存在这样一个子序列.该子序列分为三部分,第一部分与第三部分同样,第一部分与第二部分对称.假设存在求最长的符合这样的条件的序列. ...
- SPOJ STC02 - Antisymmetry(Manacher算法求回文串数)
http://www.spoj.com/problems/STC02/en/ 题意:给出一个长度为n的字符串,问其中有多少个子串s可以使得s = s按位取反+翻转. 例如样例:11001011. 10 ...
- hdu5340—Three Palindromes—(Manacher算法)——回文子串
Three Palindromes Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others ...
- 马拉车算法——求回文子串个数zoj4110
zoj的测评姬好能卡时间.. 求回文子串的个数:只要把p[i]/2就行了: 如果s_new[i]是‘#’,算的是没有中心的偶回文串 反之是奇回文串 /* 给定两个字符串s,t 结论:s,t不相同的第一 ...
- Codeforces Global Round 7 D2. Prefix-Suffix Palindrome (Hard version)(Manacher算法+输出回文字符串)
This is the hard version of the problem. The difference is the constraint on the sum of lengths of s ...
- Manacher算法求解回文字符串
Manacher算法可以在\(O(N)\)时间内求解出一个字符串的所有回文子串(正反遍历相同的字串). 注:回文串显然有两种,一种是奇数长度,如abczcba,有一个中心字符z:另外一种是偶数个长度, ...
- 马拉车算法——求回文串起点hdu3294
#include<bits/stdc++.h> using namespace std; #define maxn 500005 int p[maxn]; ]; int start; in ...
- Manacher算法 - 求最长回文串的利器
求最长回文串的利器 - Manacher算法 Manacher主要是用来求某个字符串的最长回文子串. 不要被manacher这个名字吓倒了,其实manacher算法很简单,也很容易理解,程序短,时间复 ...
- Manacher算法——求最长回文子串
首先,得先了解什么是回文串.回文串就是正反读起来就是一样的,如“abcdcba”.我们要是直接采用暴力方法来查找最长回文子串,时间复杂度为O(n^3),好一点的方法是枚举每一个字符,比较较它左右距离相 ...
随机推荐
- 那些年被我坑过的Python——摩拳擦掌(第三章)
集合类型: 集合类型中的元素是唯一的! 集合的定义与赋值: set_1 = set([1, 3, 5, 7, 2]) set_2 = set([2, 4, 6, 8, 3]) 集合的运算操作 # 交集 ...
- 升级Python至2.7.8,并安装django
1:下载Python-2.7.8.tgz2:步骤:tar -zxvf Python-2.7.8.tgzcd Python-2.7.8./configure -h --查看configure选项./co ...
- 关于SQL server的一些知识点
关于怎么打开xp_cmdshell的方法: exec sp_configure 'show advanced option',1reconfiguregoexec sp_configure 'xp_c ...
- 提高Order by语句查询效率的两个思路
提高Order by语句查询效率的两个思路 2011-03-01 13:07 水太深 ITPUB 字号:T | T 在MySQL数据库中,Order by语句的使用频率是比较高的.但是众所周知,在使用 ...
- Parencodings
Description Let S = s1 s2...s2n be a well-formed string of parentheses. S can be encoded in two diff ...
- 看奢侈品Prada如何使用物联网
这是峰哥在一家国际顶级商学院听课的笔记.这是个巨变的时代,有趣的时代. 一 PRADA在纽约的旗舰店.每件衣服上都有RFID码.每当一个顾客拿起一件PRADA进试衣间,RFID会被自动识别,试衣间里的 ...
- 【转】 java中HashMap详解
原文网址:http://blog.csdn.net/caihaijiang/article/details/6280251 java中HashMap详解 HashMap 和 HashSet 是 Jav ...
- CodeForces 591A
题目链接: http://codeforces.com/problemset/problem/591/A 题意: a,b两个相距L距离,两个分别以p,q速度从左右两个端点出发,每次相遇后,又以原来的速 ...
- Codeforces Round #326 (Div. 1) - C. Duff in the Army 树上倍增算法
题意:一个n个点的数, m个人住在其中的某些点上, 每个人的标号1-m, 询问u-v 路径上标号前a个人,并输出标号,a < 10. 作法, 利用倍增, ID[j][i] 表示i到i的第2^j个 ...
- 动态规划——线性dp
我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模 ...