• bzoj 2565: 最长双回文串 回文自动机


    题目:

    Description
    顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同)。输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分X,Y,(|X|,|Y|≥1)且X和Y都是回文串。
    Input
    一行由小写英文字母组成的字符串S。
    Output
    一行一个整数,表示最长双回文子串的长度。

    题解:

    首先我们有一个结论:(在WC2017被证明)

    • 最长的双倍回文串中一定有一个回文串是不可拓展(最长的)的.

    所以我们可以枚举取到最长的那个回文串,然后计算在剩下的字符中最长的回文串

    (len_i)表示终止在i上的最长的回文串的长度

    那么所有的(len)可以使用后缀自动机线性求出.

    这时答案就是所有的(len_i + len_{i - len_i})中的最大值.

    对吗 ??? ???

    并不对,因为这样我们实际上只是默认右面的回文串是极大的.

    并没有考虑左面的回文串取到最大值

    所以我们还应该把串倒过来再做一次.

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    inline void read(int &x){
    	x=0;char ch;bool flag = false;
    	while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
    	while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
    }
    const int maxn = 100010;
    struct PAM{
    	struct Node{
    		int nx[26];
    		int len,fail,siz;
    		Node(){
    			memset(nx,0,sizeof nx);
    			len = fail = siz = 0;
    		}
    	}T[maxn];
    	int last,nodecnt,str[maxn],len;
    	int mx[maxn];
    	inline void init(){
    		T[++nodecnt].len = -1;
    		str[len=0] = -1;
    		T[0].fail = 1;
    	}
    	PAM(){init();}
    	inline void insert(char cha){
    		int c = cha - 'a',p,cur,x;str[++len] = c;
    		for(p = last;str[len - T[p].len - 1] != str[len];p = T[p].fail);
    		if(T[p].nx[c] == 0){
    			T[cur = ++ nodecnt].len = T[p].len + 2;
    			for(x = T[p].fail;str[len - T[x].len - 1] != str[len];x = T[x].fail);
    			T[cur].fail = T[x].nx[c];T[p].nx[c] = cur;
    		}T[last = T[p].nx[c]].siz ++ ;
    		mx[len] = T[last].len;
    	}
    }P1,P2;
    char s[maxn];
    int main(){
    	scanf("%s",s+1);int n = strlen(s+1);
    	for(int i=1;i<=n;++i) P1.insert(s[i]);
    	for(int i=n;i>=1;--i) P2.insert(s[i]);
    	int ans = 0;
    	for(int i=1;i<=n;++i){
    		ans = max(ans,P1.mx[i] + P1.mx[i - P1.mx[i]]);
    		ans = max(ans,P2.mx[i] + P2.mx[i - P2.mx[i]]);
    	}printf("%d
    ",ans);
    	getchar();getchar();
    	return 0;
    }
    
  • 相关阅读:
    自动化原理
    Appium 用途和特点
    接口测试
    测试环境部署
    总结一下,selenium 自动化流程如下
    Qt---tcp之网络通信
    java的接口与抽象类
    Leetcode---每日一题之56合并区间
    java与c++的正则表达式的小总结
    数据结构学习之线索二叉树(java/c++版)
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6533849.html
Copyright © 2020-2023  润新知