zoukankan      html  css  js  c++  java
  • [SHOI2011]双倍回文

    Description

    Input

    输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容。

    Output

    输出文件只有一行,即:输入数据中字符串的最长双倍回文子串的长度,如果双倍回文子串不存在,则输出0。

    Sample Input

    16
    ggabaabaabaaball

    Sample Output

    12

    HINT

    N<=500000

    本题是一道Manacher思维好题。考虑暴力的做法,由于答案串一定形如 $ WW^RWW^R $那么我们枚举一个 i 表示整个串的中点,同时枚举 j 表示一个小串的中点,则有 p[j]+j>=x。这个不难理解,否则 p[j]+j < x 的话,我们怎么保证中间缺的一部分回文呢?同时,j 的范围为[i-p[i]/2,i),不然枚举出来的回文串长度会不够

    不过这样寻找肯定是超时的。因为要使答案最优,我们肯定是找到满足条件的一个最小的 j ,因此当某个 j 不符合条件的话,我们就没必要再考虑它了

    于是我们就可以用set,并查集,树状数组随便搞搞就过去了

    #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],fa[N*2+10];
    int find(int x){
    	if (x==fa[x])	return x;
    	return fa[x]=find(fa[x]);
    }
    int main(){
    	int len=read();
    	scanf("%s",s+1);
    	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]='^';
    	int Max=0,ID=0,ans=0;
    	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;i<=len;i++)	s[i]=='&'?fa[i]=i:fa[i]=i+1;//因为答案串一定是偶串,所以fa要指向'&' 
    	for (int i=1;i<=len;i+=2)//偶串的原因 
    		for (int j=find(max(i-p[i]/2,1));j<i;fa[j]=find(j+1),j=fa[j])
    			if (j+p[j]>i){ans=max(ans,(i-j)*2);break;}  //并查集查找优化
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Mysql mysql lost connection to server during query 问题解决方法
    【转】程序员必须知道的几个Git代码托管平台
    FIFO存储器
    JUCE_FIFO实现分析
    【转】HashMap实现原理分析
    【转】int && 非常量右值
    【API】注册表编程基础-RegCreateKeyEx、RegSetValueEx
    【API】文件操作编程基础-CreateFile、WriteFile、SetFilePointer
    【逆向知识】裸函数(Naked函数)
    【逆向知识】堆栈图-汇编中的函数
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/8414437.html
Copyright © 2011-2022 走看看