最近接触了一点字符串算法,其实也就是一个简单的最大回文串算法,给定字符串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的更多相关文章

  1. CodeForces 7D Palindrome Degree 字符串hash

    题目链接:点击打开链接 #include<stdio.h> #include<iostream> #include<string.h> #include<se ...

  2. Codeforces Beta Round #7--D. Palindrome Degree(Manacer)

    题目:http://blog.csdn.net/winddreams/article/details/44218961 求出每一个点为中心的最长字符串,推断该串是不是从开头的回文串. #include ...

  3. Codeforces Beta Round #7 D. Palindrome Degree manacher算法+dp

    题目链接: http://codeforces.com/problemset/problem/7/D D. Palindrome Degree time limit per test1 secondm ...

  4. Codeforces Beta Round #7 D. Palindrome Degree hash

    D. Palindrome Degree 题目连接: http://www.codeforces.com/contest/7/problem/D Description String s of len ...

  5. Codeforces Beta Round #7 D. Palindrome Degree —— 字符串哈希

    题目链接:http://codeforces.com/contest/7/problem/D D. Palindrome Degree time limit per test 1 second mem ...

  6. Misha and Palindrome Degree

    Misha and Palindrome Degree 题目链接:http://codeforces.com/problemset/problem/501/E 贪心 如果区间[L,R]满足条件,那么区 ...

  7. Codeforces 486C Palindrome Transformation(贪心)

    题目链接:Codeforces 486C Palindrome Transformation 题目大意:给定一个字符串,长度N.指针位置P,问说最少花多少步将字符串变成回文串. 解题思路:事实上仅仅要 ...

  8. Palindrome Degree(hash的思想题)

    个人心得:这题就是要确定是否为回文串,朴素算法会超时,所以想到用哈希,哈希从左到右和从右到左的key值一样就一定是回文串, 那么问题来了,正向还能保证一遍遍历,逆向呢,卡住我了,后面发现网上大神的秦九 ...

  9. codeforces7D Palindrome Degree(manacher&amp;dp或Hsh&amp;dp)

    D. Palindrome Degree time limit per test 1 second memory limit per test 256 megabytes input standard ...

随机推荐

  1. .net如何统计在线人数

    原文发布时间为:2008-10-17 -- 来源于本人的百度文章 [由搬家工具导入] 统计在线用户的作用不言而喻,就是为了网站管理者可以知道当前用户的多少,然后根据用户数量来观察服务器或者程序的性能, ...

  2. 调用系统文件管理器选择图片,调用系统裁剪AIP对图片处理,显示裁剪之后的图片

    package com.pingyijinren.test; import android.annotation.TargetApi; import android.app.Notification; ...

  3. hdu - 1172 猜数字 (思维题)

    http://acm.hdu.edu.cn/showproblem.php?pid=1172 这个题换一种想法,可以找出四位数中所有满足条件的数看是否只有一个. #include <iostre ...

  4. hdu - 1254 推箱子 (bfs+bfs)

    http://acm.hdu.edu.cn/showproblem.php?pid=1254 题目意思很简单,只要思路对就好. 首先考虑搬运工能否到达推箱子的那个点,这个可以根据箱子前进方向得出搬运工 ...

  5. codeforces 691E(矩阵乘法)

    E. Xor-sequences time limit per test 3 seconds memory limit per test 256 megabytes input standard in ...

  6. Servlet的HTTP状态码

    以下内容引用自http://wiki.jikexueyuan.com/project/servlet/http-status-codes.html: HTTP请求的格式和HTTP响应消息的格式是相似的 ...

  7. Android GIS开发系列-- 入门季(14)FeatureLayer之范围查询

    Android GIS开发系列-- 入门季(5),这篇文章中,我们知道如何去查找要素.现在有一个需求,查找某点5000米范围的要素,那如何来做呢?首先我们需要在地图上画个5000米半径的圆,然后根据Q ...

  8. 关于Windows 8使用WMP播放音乐时WUDFHost跑CPU和硬盘的问题解决

    Windows 8使用Windows Media Player播放音乐的时候.事实上有一个这种情况,WMP和某个什么名字看起来非常屌的进程跑CPU非常高,这个跑非常高视你插入的SD卡内的文件数或者移动 ...

  9. hdu, KMP algorithm, linear string search algorithm, a nice reference provided

    reference: Rabin-Karp and Knuth-Morris-Pratt Algorithms By TheLlama– TopCoder Member https://www.top ...

  10. 三星手机root后开启调试模式

    背景说明:三星手机高版本的手机进行root后也无法安装xposed,无法开启debuggable,使用androistdio无法进行调试. 1 .连接ddms无法显示正在运行的进程. 2.安装mpro ...