• 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;
    }
    
    
    转载需注明出处。
  • 相关阅读:
    Oracle手工增加排序区避免SQL使用临时表空间排序产生物理IO
    Oracle中"TABLE ACCESS FULL"的”欺骗时刻“
    Oracle关于12C新特性InMemory踩坑历程
    Oracle19C关于参数sec_case_sensitive_logon控制密码大小写敏感问题
    友链
    RESTful API
    不自由的自由职业
    惊了!修仙=编程??
    [Git专题] 环境搭建
    Linux系统僵尸进程详解
  • 原文地址:https://www.cnblogs.com/jz929/p/14819577.html
Copyright © 2020-2023  润新知