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

    求最长双倍回文子串。
    考虑建PAM,我们可以知道最长回文子串,但是如何知道最长双倍回文子串呢?
    我们发现如果这个子串是双倍回文子串,那么该子串<=len/2的最长回文子串一定是=len/2的,我们可以再记录一个fail'表示<=len/2的最长回文子串后缀。
    求答案的时候枚举每个位置判断fail'的len即可。
    对于fail'的求法,类似fail的求法再判断len的限制即可。
    还有一种方法,就是建完PAM以后在遍历一遍回文树,并用个桶实时存储当前每个长度的个数。每次看看有没有即可。

    或者可以用manacher来实现。

    #include<cstdio>
    #define N 500010
    #define db double
    #define ll long long
    #define fo(x,a,b) for (int x=(a);x<=(b);x++)
    #define fd(x,a,b) for (int x=(a);x>=(b);x--)
    using namespace std;
    int n,ans=0;
    char s[N];
    
    struct PAM {
    	int t[N<<1][26],len[N<<1],fail[N<<1],trans[N<<1],tot=1,las;
    	
    	void init() {
    		len[0]=0,fail[0]=trans[0]=1;
    		len[1]=-1,fail[1]=0,tot=1,las=1;
    	}
    	
    	int get_fail(int pos,int x) {
    		while (s[pos-len[x]-1]!=s[pos])
    			x=fail[x];
    		return x;
    	}
    	
    	int get_fail(int pos,int x,int son,int lim) {
    		while (s[pos-len[x]-1]!=s[pos]||len[t[x][son]]>lim)
    			x=fail[x];
    		return x;
    	}
    	
    	void ins(int x) {
    		int now=get_fail(x,las);
    		if (! t[now][s[x]-'a']) {
    			len[++tot]=len[now]+2;
    			int temp=get_fail(x,fail[now]);
    			fail[tot]=t[temp][s[x]-'a'];
    			if (len[tot]<=2) trans[tot]=fail[tot];
    			else {
    				temp=get_fail(x,trans[now],s[x]-'a',len[tot]/2);
    				trans[tot]=t[temp][s[x]-'a'];
    			}
    			t[now][s[x]-'a']=tot;
    		}
    		las=t[now][s[x]-'a'];
    	}
    	
    	int query() {
    		int res=0;
    		fo(i,2,tot) {
    			if (len[i]%4==0&&len[trans[i]]*2==len[i]) {
    				if (len[i]>res) res=len[i];
    			}
    		}
    		return res;
    	}
    }tr;
    
    int main() {
    	freopen("string.in","r",stdin);
    	freopen("string.out","w",stdout);
    	scanf("%d%s",&n,s+1);
    	tr.init();
    	fo(i,1,n) tr.ins(i);
    	ans=tr.query();
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
    转载需注明出处。
  • 相关阅读:
    break和continue
    while循环嵌套
    while循环语句
    SDUT 2766-小明传奇2(母函数)
    那些奇妙的&quot;大师&quot;是怎样炼成的(科学、迷信、心理)
    深入理解Linux字符设备驱动
    [从头学数学] 第162节 锐角三角函数
    iOS将数组中的内容分拼接成字符串
    win10 UWP 全屏
    杂(三)-The type java.lang.Object cannot be resolved It is indirectly referenced ...
  • 原文地址:https://www.cnblogs.com/jz929/p/14819577.html
Copyright © 2011-2022 走看看