POJ--3974 Palindrome(回文串,hash)

链接:点击这里

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<cstring>
using namespace std;
#define maxn 1000005
#define LL long long
#define ull unsigned long long
const LL P = 131;
ull p[maxn+10],f[maxn],ff[maxn];
int main(){
   p[0]=1;
   for(int j=1;j<=maxn;j++){
      p[j]=p[j-1]*P;
   }
   string s;
   int tot=1;
   while(cin>>s){
      if(s=="END") break;
      f[0]=0,ff[0]=0;
      int ans=0;
      int len=s.size();
      for(int j=1;j<=len;j++){
         f[j]=f[j-1]*P+s[j-1]-‘a‘+1;
      }
      for(int j=len;j>=1;j--){
        ff[j]=ff[j+1]*P+s[j-1]-‘a‘+1;
      }
      for(int j=1;j<=len;j++){
         int l=1,r=min(len-j,j),mx=0;
         while(l<=r){    // 偶数
            int mid=(l+r)/2;
            int l1=j-mid+1,r1=j;
            int l2=j+1,r2=j+mid;
            LL ll=f[r1]-f[l1-1]*p[r1-l1+1];
            LL rr=ff[l2]-ff[r2+1]*p[r2-l2+1];
            if(ll==rr){
               mx=max(mx,mid);
               l=mid+1;
            }else r=mid-1;
         }
         ans=max(ans,2*mx);
         l=1,r=min(len-j,j-1),mx=0;
         while(l<=r){     //奇数
            int mid=(l+r)/2;
            int l1=j-mid,r1=j-1;
            int l2=j+1,r2=j+mid;
            LL ll=f[r1]-f[l1-1]*p[r1-l1+1];
            LL rr=ff[l2]-ff[r2+1]*p[r2-l2+1];
            if(ll==rr){
               mx=max(mx,mid);
               l=mid+1;
            }else r=mid-1;
         }
         ans=max(ans,2*mx+1);
      }
      //cout<<ans<<endl;
      printf("Case %d: %d\n",tot++,ans);
   }
   return 0;
}

原文地址:https://www.cnblogs.com/DyLoder/p/10200569.html

时间: 2024-10-13 03:33:51

POJ--3974 Palindrome(回文串,hash)的相关文章

poj 1159 Palindrome -- 回文串,动态规划

Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 59029   Accepted: 20505 Description A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a

BZOJ 2565 最长双回文串 Hash+二分

题目大意:给定一个字符串,求一个最长的子串,该字串可以分解为两个回文子串 傻逼的我又忘了Manacher怎么写了= = 无奈Hash+二分吧 首先将字符串用分隔符倍增,然后求出以每个点为中心的最长回文半径 然后考虑两个回文串怎么合并成一个 我们发现图中以i为中心的回文串和以j为中心的回文串合并后长度恰好为(j-i)*2 能合并的前提是以两个点为中心的回文串有交点 那么对于每个j我们要求出有交点的最左侧的i 维护一个后缀min随便搞搞就可以了 #include <cstdio> #include

POJ 1159-Palindrome(dp_回文串+滚动数组)

Palindrome Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Description A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to wr

【Foreign】回文串 [hash]

回文串 Time Limit: 10 Sec  Memory Limit: 256 MB Description ASDFZ 的机房中不仅有红太阳,还有蓝太阳和原谅色太阳. 有一天,太阳们来到机房,发现桌上有不知 道哪个蒟蒻放上的问题: 令 F (A,B) 表示选择一个串 A 的非空前缀 S 和串 B 的非空后缀 T 使得将串 S 和串 T 拼起来之后是回 文串的方案数. 现在给定两个串 A 和 B,令 Ai 表示串 A 的第 i 长的后缀,Bi 为串 B 的第 i 长的前缀. 有 Q 组询问,

HDU 1513[Palindrome] 回文串

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1513 题目大意:给一个字符串,问最少加多少个字母能成为回文串. 关键思想:要解决的是回文子序列问题而不是回文子串.回文子序列怎么求?可以把字符串倒转一下,再求他们的最长公共子序列啊!想一想为什么.求出LCS长度之后,n-LCS才是我们要的答案,因为对于不是回文子序列的其他字符来说,都需要给他们一个对象才能回文(对称).还有一个问题是我们开不了5000*5000的数组,但观察到递推方程是只与两个状态有

POJ 3974 回文串-Manacher

题目链接:http://poj.org/problem?id=3974 题意:求出给定字符串的最长回文串长度. 思路:裸的Manacher模板题. #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> using namespace std; const int MAXN=10

POJ 3280 Cheapest Palindrome(区间DP求改成回文串的最小花费)

题目链接:http://poj.org/problem?id=3280 题目大意:给你一个字符串,你可以删除或者增加任意字符,对应有相应的花费,让你通过这些操作使得字符串变为回文串,求最小花费.解题思路:比较简单的区间DP,令dp[i][j]表示使[i,j]回文的最小花费.则得到状态转移方程: dp[i][j]=min(dp[i][j],min(add[str[i]-'a'],del[str[i]-'a'])+dp[i+1][j]); dp[i][j]=min(dp[i][j],min(add[

URAL 1989 Subpalindromes(回文串 线段树 多项式hash)

1989. Subpalindromes Time limit: 0.5 second Memory limit: 64 MB You have a string and queries of two types: replace i'th character of the string by character a; check if substring sj...sk is a palindrome. Input The first line contains a string consis

Valid Palindrome ——判断字符串是否为回文串

本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/41488377 Valid Palindrome Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. For example, "A man, a plan, a canal: Panama&

URAL 1297. Palindrome(后缀数组求最大回文串)

题目大意:给你一串字符串,让你求出来它存在的最长连续的回文串. 解题思路:先把字符串逆序加到数组中,然后用后缀数组求解.两种方法:1,枚举排名,直接比较rank相同的字符串的位置差是不是len.如果是的话,就记录求解:2,枚举地址,求第i地址与第2*len-i+1的lcp的最大值. PS:需要注意如果多解输出靠前的字符串. 两种写法写在了一起,分别是Del,和Del1函数. 1297. Palindrome Time limit: 1.0 second Memory limit: 64 MB T