CodeForces - 7D Palindrome Degree
最近接触了一点字符串算法,其实也就是一个简单的最大回文串算法,给定字符串s,求出最大字符串长度。
算法是这样的, 用'#'将s字符串中的每个字符分隔,比如s = “aba”,分割后变成#a#b#a#,然后利用下面的算法:
pre:
mx ←0
for i: = 1 to n-1
if(mx>i)
p[i] = min(p[2*id-i], mx-i)
else p[i] = 1
while(str[i+p[i]] == str[i-p[i]])
p[i]++
if(i+p[i]>mx)
mx = i+p[i]
id = i
注意在将s添加'#'之后为了防止越界访问,需要再整个字符串前面加上’$’这样i就是从1开始,p[i]表示在字符中以i为中心的回文串的右半长度,准确的说是r-i+1,r为回文串最右边的字符的下标,
mx表示i之前的位置j的回文串最大右端值,然后每次循环结束的时候更新mx并用id记录i值。
本题求的是字符串s的所有的前缀字符串的k值,k值是这样的定义的,也就是对一个回文串进行二分,分得的两部分仍然是回文串就将s字符串的k值增加1,然后继续分,直到不是回文串。
由于字符串k值取决于自身是不是回文串,所以要先进行判断,然后f[str] = f[substr] + 1,substr表示为str的前半部分的k值,由于substr应该在前面求出了,所以整个过程可以是一个dp过程。
代码:
#include <iostream>
#include <sstream>
#include <cstdio>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <string>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#define esp 1e-6
#define pi acos(-1.0)
#define pb push_back
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define mp(a, b) make_pair((a), (b))
#define in freopen("in.txt", "r", stdin);
#define out freopen("out.txt", "w", stdout);
#define print(a) printf("%d\n",(a));
#define bug puts("********))))))");
#define stop system("pause");
#define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
#define inf 0x0f0f0f0f using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int, int> pii;
typedef vector<pii> VII;
typedef vector<pii, int> VIII;
typedef VI:: iterator IT;
const int maxn = 5*1000000+100;
char str[maxn<<1], s[maxn];
int p[maxn<<1];
int ans;
int n;
int f[maxn<<1];
void Init(void)
{
str[0] = '$', str[1] = '#';
for(int i = 0; i < n; i++)
{
str[i*2+2] = s[i];
str[i*2+3] = '#';
}
int nn = 2*n+2;
str[nn] = 0;
int mx = 0, id;
for(int i = 1; i < nn; i++)
{
if(mx > i)
{
p[i] = min(p[2*id-i], mx-i);
}
else p[i] = 1;
while(str[i+p[i]] == str[i-p[i]])
p[i]++;
if(i + p[i] > mx)
mx = i+p[i],
id = i;
}
}
void solve(void)
{
LL ans = 0;
for(int i = 1; i <= n; i++)
{
int l = 2, r = 2*i;
int m = (l+r)>>1;
if(p[m]*2-1 >= r-l+1)
f[r] = f[m-1+((m%2) ? 0: -1)]+1;
ans += f[r];
}
printf("%I64d\n", ans);
} int main(void)
{
scanf("%s", s);
n = strlen(s);
Init();
solve();
return 0;
}
更详细的介绍在这里:http://www.cnblogs.com/wuyiqi/archive/2012/06/25/2561063.html
CodeForces - 7D Palindrome Degree的更多相关文章
- CodeForces 7D Palindrome Degree 字符串hash
题目链接:点击打开链接 #include<stdio.h> #include<iostream> #include<string.h> #include<se ...
- Codeforces Beta Round #7--D. Palindrome Degree(Manacer)
题目:http://blog.csdn.net/winddreams/article/details/44218961 求出每一个点为中心的最长字符串,推断该串是不是从开头的回文串. #include ...
- Codeforces Beta Round #7 D. Palindrome Degree manacher算法+dp
题目链接: http://codeforces.com/problemset/problem/7/D D. Palindrome Degree time limit per test1 secondm ...
- Codeforces Beta Round #7 D. Palindrome Degree hash
D. Palindrome Degree 题目连接: http://www.codeforces.com/contest/7/problem/D Description String s of len ...
- Codeforces Beta Round #7 D. Palindrome Degree —— 字符串哈希
题目链接:http://codeforces.com/contest/7/problem/D D. Palindrome Degree time limit per test 1 second mem ...
- Misha and Palindrome Degree
Misha and Palindrome Degree 题目链接:http://codeforces.com/problemset/problem/501/E 贪心 如果区间[L,R]满足条件,那么区 ...
- Codeforces 486C Palindrome Transformation(贪心)
题目链接:Codeforces 486C Palindrome Transformation 题目大意:给定一个字符串,长度N.指针位置P,问说最少花多少步将字符串变成回文串. 解题思路:事实上仅仅要 ...
- Palindrome Degree(hash的思想题)
个人心得:这题就是要确定是否为回文串,朴素算法会超时,所以想到用哈希,哈希从左到右和从右到左的key值一样就一定是回文串, 那么问题来了,正向还能保证一遍遍历,逆向呢,卡住我了,后面发现网上大神的秦九 ...
- codeforces7D Palindrome Degree(manacher&dp或Hsh&dp)
D. Palindrome Degree time limit per test 1 second memory limit per test 256 megabytes input standard ...
随机推荐
- Eclipse配置SVN的几种方法及使用详情
此文章对Myeclipse同样适用. 一.在Eclipse里下载Subclipse插件 方法一:从Eclipse Marketplace里面下载 具体操作:打开Eclipse --> Help ...
- 使用流的方式去进行post请求解决中文乱码问题返回xml格式
/** * 请求post * @Title: getHttpURLConnection * @Description: TODO(这里用一句话描述这个方法的作用) * @param: @param u ...
- hdu - 1394 Minimum Inversion Number(线段树水题)
http://acm.hdu.edu.cn/showproblem.php?pid=1394 很基础的线段树. 先查询在更新,如果后面的数比前面的数小肯定会查询到前面已经更新过的值,这时候返回的sum ...
- Rikka with Phi 线段树
Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds ...
- AndroidStudio NDK开发、调试测试工程
## 验证内容:1.支持NDK调试 2.支持native方法快速创建jni封装(但是没有加入extern "C"声明,会导致native方法找不到jni,进而报错) 3.支持通过修 ...
- 【每日算法】排序算法总结(复杂度&稳定性)
一.插入排序:稳定,时间复杂度O(n^2) 想象你在打扑克牌,一開始左手是空的,接着右手開始从桌上摸牌,并将其插入到左手的一把牌中的正确位置上.为了找到这个正确位置,我们须要从右到左将它与手中的牌比較 ...
- Django打造大型企业官网(五)
4.6.切换轮播图的箭头样式以及显示和隐藏 templates/news/index.html <span class="arrow left-arrow">‹< ...
- @SessionAttributes的覆盖与加入
在我们使用@SessionAttributes 注解向session加入对象时.当我们使用ModelMap的addAttribute()方法是指向session中加入一个新的对象,而使用HttpSes ...
- qq xxs
qq xxs qq xxs 有很多举个简单例子 : QQ空间发段文章 带上 <script> 提交(document.cookie) 到 自己服务端获取 </script> 在 ...
- STL 之 list源码自行实现(iterator)
(0)文件夹 STL 之 vector源码实现(云算法<< [] = 重载, new delete,throw catch) STLc++中string类的源码 堆(stack) 之 c ...