zoukankan      html  css  js  c++  java
  • [BZOJ2565]最长双回文串

    bzoj

    题意

    输入长度为(n)的串(S),求(S)的最长双回文子串(T),即可将(T)分为两部分(X,Y)((|X|,|Y|≥1))(X)(Y)都是回文串。

    sol

    显然是枚举(X)(Y)在那个地方断吧。
    那么就需要求出位置(i)的最长回文后缀和(i+1)的最长回文前缀,然后拼起来就可以了。
    回文后缀可以直接回文树求。
    回文前缀?
    (reverse)过来再做一遍即可。

    code

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N = 1e5+5;
    struct Palindromic_Tree{
    	int last,tot,tr[N][26],fa[N],len[N];
    	void init(){fa[0]=fa[1]=1;len[tot=1]=-1;}
    	void extend(int c,int n,char *s)
    		{
    			int v=last;
    			while (s[n-len[v]-1]!=s[n]) v=fa[v];
    			if (!tr[v][c])
    			{
    				int u=++tot,k=fa[v];
    				len[u]=len[v]+2;
    				while (s[n-len[k]-1]!=s[n]) k=fa[k];
    				fa[u]=tr[k][c];tr[v][c]=u;
    			}
    			last=tr[v][c];
    		}
    }t1,t2;
    char s[N];int f[N],g[N];
    int main()
    {
    	scanf("%s",s+1);
    	int n=strlen(s+1),ans=0;
    	t1.init();t2.init();
    	for (int i=1;i<=n;++i) t1.extend(s[i]-'a',i,s),f[i]=t1.len[t1.last];
    	reverse(s+1,s+n+1);
    	for (int i=1;i<=n;++i) t2.extend(s[i]-'a',i,s),g[n-i+1]=t2.len[t2.last];
    	for (int i=1;i<n;++i) ans=max(ans,f[i]+g[i+1]);
    	printf("%d
    ",ans);return 0;
    }
    
  • 相关阅读:
    javascript 字符串截取
    HTML5 转
    Javascript try catch finally
    C#之json字符串转xml字符串
    AspNetCore Json序列化设置
    类加载(对象创建)顺序
    线性表,线性表和链表的区别
    Implement int sqrt(int x).
    Add Binary
    Roman to Integer(将罗马数字转成整数)
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8684529.html
Copyright © 2011-2022 走看看