最近接触了一点字符串算法,其实也就是一个简单的最大回文串算法,给定字符串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. 2018/3/3 解析ThreadLocal源码

    今天听到一个老哥说道ThreadLocal在源码设计上面的一些好处,于是决定把ThreadLocal源码彻底分析一下. 首先,我们来看下set方法 可以看到,这个方法里,先获得了当前线程,之后将当前线 ...

  2. 静态区间第k大(划分树)

    POJ 2104为例[经典划分树问题] 思想: 利用快速排序思想, 建树时将区间内的值与区间中值相比,小于则放入左子树,大于则放入右子树,如果相等则放入左子树直到放满区间一半. 查询时,在建树过程中利 ...

  3. wget: unable to resolve host address “mirrors.163.com” 的解决办法

    wget:无法解析主机地址.这就能看出是DNS解析的问题. 解决办法: 登入root(VPS). 进入/etc/resolv.conf. 修改内容为下nameserver 8.8.8.8 #googl ...

  4. Django学习系列之Form验证

    django表单基础 django表单分类 基于django.forms.Form:所有表单类的父类 基于django.forms.ModelForm:可以和模型类绑定的Form Form验证流程 定 ...

  5. [TypeScript] Represent Non-Primitive Types with TypeScript’s object Type

    ypeScript 2.2 introduced the object, a type that represents any non-primitive type. It can be used t ...

  6. C# VS如何整个项目中查找字符串

    Ctrl+F打开查找对话框,然后输入查找字符串,电机右边的小三角,选择整个解决方案,就可以遍历所有文件查找指定字符了                                

  7. Python3标准库(二) re模块

    正则表达式(Regular Expression)是字符串处理的常用工具,通常被用来检索.替换那些符合某个模式(Pattern)的文本.很多程序设计语言都支持正则表达式,像Perl.Java.C/C+ ...

  8. MYSQL入库常用PHP函数

    addslashes   addslashes() 函数在指定的预定义字符前添加反斜杠.这些字符是单引号(').双引号(").反斜线(\)与NUL(NULL字符).   stripslash ...

  9. navicat软件设置连接mysql数据库

    navicat软件设置连接mysql数据库 适用范围及演示使用工具 适用范围:mysql全部系列(含Linux和Windows系统下的mysql) 演示使用工具:Navicat 8.0 MySQL 演 ...

  10. (五)Java 对象和类

    Java 对象和类 Java作为一种面向对象语言.支持以下基本概念: 多态 继承 封装 抽象 类 对象 实例 方法 消息解析 本节我们重点研究对象和类的概念. 对象:对象是类的一个实例,有状态和行为. ...