最近接触了一点字符串算法,其实也就是一个简单的最大回文串算法,给定字符串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. POJ 3169_Layout

    大早上水一发=.= 题意: n头牛按编号顺序站成一列,给定n头牛之间的位置关系,求出第n头牛和第一头牛之间的最大距离. 分析: 差分约束系统,这题不等式关系还是挺好找的.注意因为按照顺序排列,所以有d ...

  2. CCCC2017大区赛补完

    L2-2 多项式除法 这题看懂题意就是个模拟 L3-2 周游世界 想法是相邻点连边,然后跑最短路,当最短路相同时候,比较之前经过的换乘数,取最小的作为方案 但是这样只过了2个点……? 网上dalao们 ...

  3. 对于事务ACID的理解

    ACID,即以下四点: 原子性(Atomicity) 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生. 一致性(Consistency) 事务前后数据的完整性必须保持一致 ...

  4. Ubuntu系统备份工具大全(官方整理推荐)

    其实官方在系统备份这块已经有Wiki整理和收集各类实用的工具.以下是翻译自官方Wiki的部分文档: 备份工具  wiki文档实用程序 工具 界面 格式类型 Raw/File 支持 远程 增量 差异 自 ...

  5. JSP的文件上传

    以下内容引用自http://wiki.jikexueyuan.com/project/jsp/file-uploading.html: 一个JSP可以用一个HTML表单标签,它允许用户上传文件到服务器 ...

  6. TCP打洞与UDP打洞的差别

    为什么网上讲到的P2P打洞基本上都是基于UDP协议的打洞?难道TCP不可能打洞?还是TCP打洞难于实现?     如果如今有内网clientA和内网clientB.有公网服务端S.     如果A和B ...

  7. laravel5.4新特性

    http://www.cnblogs.com/webskill/category/1067140.html laravel 5.4 新特性 component and slot 使用: 1.compo ...

  8. Logstash学习系列之插件介绍

    Logstash插件获取方式 插件获取地址: https://github.com/logstash-plugins  在线安装: /plugin install logstash-input-jdb ...

  9. A. Polo the Penguin and Strings

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...

  10. 菜鸟学python-基础(2)

    变量命名: 1)必须以字符或下划线开头 2)以单下划线开头(_fo)表示不能直接訪问的类属性,须要类提供的接口进行訪问 3)以双下划线开头(__foo)的代表类的私有成员 4)以双下划线开头(__fo ...