• [BZOJ2565]最长双回文串


    Description

    顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同)。
    输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分X,Y,(|X|,|Y|≥1)且X和Y都是回文串。

    Input

    一行由小写英文字母组成的字符串S。2≤|S|≤10^5

    Output

    一行一个整数,表示最长双回文子串的长度

    Sample Input
    baacaabbacabb

    Sample Output
    12
    //从第二个字符开始的字符串aacaabbacabb可分为aacaa与bbacabb两部分,且两者都是回文串。


    首先一遍Manacher,然后记录下两个数组——l,r

    l[i] 代表所有包含 s[i] 的回文串的最左端点(一个回文串的最右端点的 l 不等于该回文串的最左端点)
    r[i] 代表所有包含 s[i] 的回文串的最右端点(一个回文串的最左端点的 r 不等于该回文串的最右端点)

    有什么用?答案就是 max{r[i]-l[i]}(1<=i<=len)

    正确性?其实 r[i]-l[i] 非常好理解,关键是上文括号内的东西有点奇怪。其实不难,因为两个回文串之间要有联系,不能相互独立,所以一个回文串的最右端点记录的 l 不能是本身的左端点,而是其他点的值

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x>=10)     print(x/10);
    	putchar(x%10+'0');
    }
    const int N=5e5;
    char s[N*2+10];
    int p[N*2+10],l[N*2+10],r[N*2+10];
    int main(){
    	scanf("%s",s+1);
    	int len=strlen(s+1),Max=0,ID=0,ans;
    	for (int i=len;i;i--)	s[i<<1]=s[i],s[i<<1|1]='&';
    	len=len<<1|1;
    	s[0]='#',s[1]='&',s[len+1]='^';
    	for (int i=1;i<=len;i++){
    		p[i]=Max>i?min(p[ID*2-i],Max-i):1;
    		while (s[i-p[i]]==s[i+p[i]])	p[i]++;
    		if (Max<p[i]+i)	Max=p[ID=i]+i;
    	}
    	for (int i=1,t=1;i<=len;i++)	for (;t<i+p[i];t++)	l[t]=i;  //l的线性求法,很好理解,这里便不再赘述
    	for (int i=len,t=len;i;i--)     for (;t>i-p[i];t--)	r[t]=i;  //r同理
    	for (int i=2;i<len;i+=2)	ans=max(ans,r[i]-l[i]);  //求答案的时候只需要考虑读入的字符串,不用枚举添加的字符
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Linux安装oracle 10g常见问题之——ORA-01078,LRM-00109,ORA-01102
    Linux安装oracle 10g常见问题之——OUI-25031
    C#中static静态变量的用法
    让DIV中的内容水平和垂直居中
    json对象与json字符串互换
    AJAX请求 $.post方法的使用
    .NET(c#)new关键字的三种用法
    创建数据库和表的SQL语句
    SQL、LINQ、Lambda 三种用法(转)
    AJAX中UPDATEPANEL配合TIMER控件实现局部无刷新
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/8414476.html
Copyright © 2020-2023  润新知