[POJ 3974] Palindrome (字符串哈希+二分)

原创 2016年08月30日 21:05:59

链接

POJ 3974


题意

给出字符串,求其最长回文子串的长度。


思路

该题目可用manacher算法在O(n)时间内解决。
最长回文子串,也是子串+长度类型的问题,此处使用字符串哈希+二分解决。
对字符串进行正序倒序两次哈希,之后二分长度,对每个长度len枚举子串的哈希值,判断相同位置的子串正逆序哈希值是否相同,相同则代表为回文串。
复杂度O(n*log(n))。


代码

#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
typedef unsigned long long ulint;
const ulint seed = 30007uLL;
#define maxn 1010000
ulint H[maxn], P[maxn], xp[maxn];
char s[maxn];
int N;

void initHash()
{
    H[0] = s[0];
    for(int i = 1; i < N; i++)
        H[i] = H[i - 1]*seed + s[i];

    P[N-1] = s[N-1];
    for(int i = N-2; i >= 0; i--)
        P[i] = P[i + 1]*seed + s[i];
}

ulint askHash(int l, int r)
{
    if(l == 0) return H[r];
    return H[r] - H[l - 1]*xp[r - l + 1];
}

ulint askP(int l, int r)
{
    if(r == N-1) return P[l];
    return P[l] - P[r + 1]*xp[r - l + 1];
}


bool check(int len)
{
    //cout << "len = " << len << endl;
    ulint ht, pt;

    for(int i = 0, l, r; i + len - 1 < N; i++)
    {
        l = i, r = i + len - 1;
        ht = askHash(l, r);
        pt = askP(l, r);

        //cout << ht << " " << pt << endl;

        if(ht == pt) return true;
    }

    return false;
}


int main()
{
    xp[0] = 1;
    for(int i = 1; i < maxn; i++)
    {
        xp[i] = xp[i-1] * seed;
    }

    int kase = 0;
    while(~scanf("%s", &s))
    {
        if(string(s) == string("END"))
            break;

        N = strlen(s);
        for(int i = 0; i < N; i++)
        {
            s[i] = s[i] - 'a' + 1;
        }

        initHash();
/*
        for(int i = 0; i < N; i++)
        {
            cout << askHash(i, i) << " " << askP(i, i) << endl;
        }
*/


        vector<int> dexod, dexev;
        for(int i = 1; i <= N; i++)
        {
            if(i % 2) dexod.push_back(i);
            else dexev.push_back(i);
        }

        int ans = 0, l = 0, r = dexod.size() - 1, m;
        while(l <= r)
        {
            m = (l + r) >> 1;

            if(check(dexod[m]))
            {
                l = m + 1;
                ans = dexod[m];
            }
            else r = m - 1;
        }

        l = 0, r = dexev.size() - 1;
        while(l <= r)
        {
            m = (l + r) >> 1;

            if(check(dexev[m]))
            {
                l = m + 1;
                ans = max(ans, dexev[m]);
            }
            else r = m - 1;
        }

        printf("Case %d: ", ++kase);
        cout << ans << endl;
    }
    return 0;
}
版权声明:想转就转吧,反正也是人人都会的东西:-( 举报

相关文章推荐

[POJ 3974] Palindrome (字符串哈希+二分)

链接POJ 3974题意给出字符串,求其最长回文子串的长度。思路该题目可用manacher算法在O(n)时间内解决。 最长回文子串,也是子串+长度类型的问题,此处使用字符串哈希+二分解决。 对字符...

poj-2774 二分+字符串哈希+二分

给两个最多100000长度的字符串,求出他们的最长公共子串。         最长公共子串存在单调性 -- 如果两个串存在长度为k的公共子串,那么必然存在长度0到k-1的公共子串。 利用其单调性,先二...
  • HTT_H
  • HTT_H
  • 2015-01-18 20:43
  • 485

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

[POJ 2774] Long Long Message (字符串哈希+二分)

链接POJ 2774题意给出两个字符串,寻找其最长公共子串。 注意字符串的长度较大,100000。思路字符串哈希典型问题,寻找N个字符串的最长公共子串。对于N个长度不超过L的字符串,哈希可以在O(N...

[POJ 1743] Musical Theme (字符串哈希+二分)

链接POJ 1743题意给出一个序列,元素范围1到88,求出最长连续子序列长度,满足该序列(或该序列的逆序)在序列中出现过至少2次并且不相交(没有公共部分)。思路又是子串+长度问题,可用哈希+二分解决...

POJ 3974 Palindrome 回文串

求最长回文串  由于数据大  需要O(n)的算法  Manacher算法 这个算法有一个很巧妙的地方,它把奇数的回文串和偶数的回文串统一起来考虑了。这一点一直是在做回文串问题中时比较烦的地...

【JZOJ 3870】单词检索

Description小可可是学校图书馆的管理员,现在他接手了一个十分棘手的任务。 由于学校需要一些材料,校长需要在文章中检索一些信息。校长一共给了小可可N篇文章,每篇文章为一个字符串。现在,校长需...

字符串哈希

常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法。这些函数使用位运算使得每一个字符都对最后的函数值产生影响。另外还有以MD5和SHA1为代表的杂凑函数,这些函数几乎...

poj 3007 Organize Your Train part II (字符串哈希)

这应该是一道考STL的题,然而用STL试过2^n遍后,只剩下伤心与落泪 没办法,还是得用字符串哈希 #include #include #include #include #inclu...

poj1200(字符串哈希)

点击打开题目链接 题意就是,给出一个字符串,里面有NC个不同字符,求其中长度为n的不同子字符串个数 差不多就是字符串的哈希算法的一道简单应用题了,《挑战程序设计竞赛》书上第373页开始有相关内容 ...

POJ 3974 Palindrome manacher

题目链接:HDU3974 Palindrome Time Limit: 15000MS   Memory Limit: 65536K Total Submis...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)