BZOJ 2565 最长双回文串 Hash+二分
2015-02-24 17:04
253 查看
题目大意:给定一个字符串,求一个最长的子串,该字串可以分解为两个回文子串
傻逼的我又忘了Manacher怎么写了= = 无奈Hash+二分吧
首先将字符串用分隔符倍增,然后求出以每个点为中心的最长回文半径
然后考虑两个回文串怎么合并成一个
![](http://img.blog.csdn.net/20150224170126778)
我们发现图中以i为中心的回文串和以j为中心的回文串合并后长度恰好为(j-i)*2
能合并的前提是以两个点为中心的回文串有交点
那么对于每个j我们要求出有交点的最左侧的i
维护一个后缀min随便搞搞就可以了
傻逼的我又忘了Manacher怎么写了= = 无奈Hash+二分吧
首先将字符串用分隔符倍增,然后求出以每个点为中心的最长回文半径
然后考虑两个回文串怎么合并成一个
我们发现图中以i为中心的回文串和以j为中心的回文串合并后长度恰好为(j-i)*2
能合并的前提是以两个点为中心的回文串有交点
那么对于每个j我们要求出有交点的最左侧的i
维护一个后缀min随便搞搞就可以了
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 200200 #define BASE 131 using namespace std; typedef unsigned long long ll; int n,ans; int f[M],min_pos[M]; char s[M]; ll hash1[M],hash2[M],power[M]; bool Judge(int mid,int len) { ll _hash1=hash1[mid+len-1]-hash1[mid-1]*power[len]; ll _hash2=hash2[mid-len+1]-hash2[mid+1]*power[len]; return _hash1==_hash2; } int Bisecition(int x) { int l=1,r=min(x,n-x+1); while(l+1<r) { int mid=l+r>>1; if( Judge(x,mid) ) l=mid; else r=mid; } return Judge(x,r)?r:l; } int main() { int i; static char str[M]; scanf("%s",str+1); for(s[1]='#',i=1;str[i];i++) s[i<<1]=str[i],s[i<<1|1]='#'; n=strlen(s+1); for(power[0]=1,i=1;i<=n;i++) power[i]=power[i-1]*BASE; for(i=1;i<=n;i++) hash1[i]=hash1[i-1]*BASE+s[i]; for(i=n;i;i--) hash2[i]=hash2[i+1]*BASE+s[i]; memset(min_pos,0x3f,sizeof min_pos); for(i=1;i<=n;i++) { f[i]=Bisecition(i); min_pos[i+f[i]-1]=min(min_pos[i+f[i]-1],i); } for(i=n-1;i;i--) min_pos[i]=min(min_pos[i],min_pos[i+1]); for(i=1;i<=n;i++) { int temp=min_pos[i-f[i]+1]; ans=max(ans,i-temp<<1); } cout<<(ans>>1)<<endl; return 0; }
相关文章推荐
- BZOJ[2565]最长双回文串 Manacher
- BZOJ 2565: 最长双回文串 manacher
- BZOJ 2565: 最长双回文串 manacher
- 【bzoj 2565】最长双回文串(manacher)
- 【bzoj2565】最长双回文串
- BZOJ_2565_最长双回文串_manacher
- 【BZOJ】【2565】最长双回文串
- 最长双回文串 bzoj 2565 回文自动机
- [BZOJ]2565 最长双回文串 Manacher+单调队列
- BZOJ 2565 最长双回文串
- BZOJ 2565 最长双回文串 Manacher
- [bzoj 2565] 最长双回文串
- BZOJ 2565 最长双回文串
- BZOJ 2565 最长双回文串(哈希)
- BZOJ2565 最长双回文串(回文树)
- BZOJ 2565 最长双回文串 哈希+二分+线扫+树状数组
- bzoj2565 最长双回文串
- BZOJ 2565 最长双回文串 (Manacher)
- bzoj2565 最长双回文串
- 2565: 最长双回文串 - BZOJ