最近接触了一点字符串算法,其实也就是一个简单的最大回文串算法,给定字符串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. 【bzoj1922】[Sdoi2010]大陆争霸 - STL - dijkstra

    信仰斯普林·布拉泽的克里斯国教徒. 幻想历 8012年 3月2日,位于杰森国东部小镇神谕镇的克里斯国教徒发动 起义. 幻想历 8012年 3月7日,神谕镇的起义被杰森国大军以残酷手段镇压. 幻想历 8 ...

  2. 网易2018校招 合唱 DP

      时间限制:2秒 空间限制:131072K 小Q和牛博士合唱一首歌曲,这首歌曲由n个音调组成,每个音调由一个正整数表示.对于每个音调要么由小Q演唱要么由牛博士演唱,对于一系列音调演唱的难度等于所有相 ...

  3. Java日期LocalDate使用

    在做报表统计时,需要对指定时间内的数据做统计,则需要使用到时间日期API 在此使用的是java.util.Date的完美私生子LocalDate类 LocalDate方法介绍 now() : 从默认时 ...

  4. oracle链接不上的问题

    使用plSql连接数据库看看,登录提示如下:ORA-12514:TNS:监听程序当前无法识别连接描述符中请求的服务. 查了许久的baidu也没有解决问题的方法.想起来看看oracle的服务是否开启,O ...

  5. Ubuntu 16.04桌面打开终端自动进去桌面文件夹

    sudo vim ~/.bashrc #在最后添加如下内容,注意,由于我的系统是中文版本,所以文件夹名称为“桌面”,如果为英文版的,那么需要更改为“Desktop” if [[ $PWD == $(r ...

  6. Jmeter技巧

    Jmeter参数化的4种方法 用Jmeter测试时包含两种情况的参数,一种是在url中,一种是请求中需要发送的参数. URL中的参数,如:http://blog.da-fang.com/index.p ...

  7. Hadoop之——HBASE结合MapReduce批量导入数据

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46463889 废话不多说.直接上代码,你懂得 package hbase; imp ...

  8. JS 通过选择百度地图地址获取经纬度自动填充到文本框中的方法

    首先要注册百度地图API. 1.登录百度地图开放平台http://lbsyun.baidu.com 注册账号,完善信息,点击网站右上角的“API控制台”,点击,创建应用. 应用类型选择:“浏览器端”, ...

  9. bootrap 手风琴Collapse源码分析

    /* ======================================================================== * Bootstrap: collapse.js ...

  10. [翻译]NUnit---Exception && Utility Methods (六)

    网址:http://www.cnblogs.com/kim01/archive/2013/04/01/2994378.html Exception Asserts (NUnit 2.5) Assert ...