• [LuoguP4287][SHOI2011]双倍回文(回文自动机)


    [LuoguP4287][SHOI2011]双倍回文(回文自动机)

    题面

    定义一个字符串为"双倍回文",当且仅当它是回文串,长度为4的倍数,且前一半和后一半的字符串都是回文串。如( exttt{abbaabba})

    给出一个字符串(S),求它的最长双倍回文子串的长度。

    (|S|leq 5 imes 10^5)

    分析

    对于PAM上的每个节点,我们维护(trans),代表小于等于当前节点串长度一半的最长回文后缀,指向对应后缀的节点.求法和fail基本一样。

    int y=t[p].trans;
    while(s[pos-len(y)-1]!=s[pos]||(len(y)+2)*2>len(cur)) y=fail(y);
    t[cur].trans=t[y].ch[c]; 
    //和getfail类似,注意转移过来加了c之后长度为len(y)+2 
    

    然后对于每个节点,判断(2len(trans(i)))是否等于当前长度(len(i)),且(4|len(i))

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring> 
    #define maxn 500000
    #define maxc 26
    using namespace std;
    char s[maxn+5];
    struct PAM{
    #define fail(x) (t[x].fail)
    #define len(x) (t[x].len)
    	struct node{
    		int ch[maxc];
    		int fail;
    		int len;
    		int trans;
    	}t[maxn+5];
    	int ptr,last;
    	void ini(){
    		ptr=1;
    		t[0].fail=1;
    		t[1].fail=0;
    		len(0)=0;
    		len(1)=-1;
    		last=0;
    	} 
    	inline int get_fail(int x,int n){
    		while(s[n-len(x)-1]!=s[n]) x=fail(x);
    		return x;
    	}
    	void insert(int c,int pos){
    		int p=get_fail(last,pos);
    		if(t[p].ch[c]==0){
    			int cur=++ptr;
    			len(cur)=len(p)+2;
    			fail(cur)=t[get_fail(fail(p),pos)].ch[c];
    			t[p].ch[c]=cur;
    			if(len(cur)<=2) t[cur].trans=fail(cur);
    			else{
    				int y=t[p].trans;
    				while(s[pos-len(y)-1]!=s[pos]||(len(y)+2)*2>len(cur)) y=fail(y);
    				t[cur].trans=t[y].ch[c]; 
    				//和getfail类似,注意转移过来加了c之后长度为len(y)+2 
    			}
    		}
    		last=t[p].ch[c];
    	}
    	int calc(){
    		int ans=0;
    		for(int i=2;i<=ptr;i++){
    			if(len(t[i].trans)*2==len(i)&&len(i)%4==0) ans=max(ans,len(i));
    		}
    		return ans;
    	}
    }T;
    int n;
    int main(){
    	scanf("%d",&n);
    	scanf("%s",s+1);
    	T.ini();
    	for(int i=1;i<=n;i++) T.insert(s[i]-'a',i);
    	printf("%d
    ",T.calc());
    }
    
    
  • 相关阅读:
    PHP date函数时间相差8个小时解决办法
    PHP中include()与require()的区别说明
    post与get区别
    MFC 对话框控件自动布局
    Apache php Mysql部署(一)下载安装
    apache 重定向
    clistctrl失去焦点高亮显示选中行
    格式化字符串
    unicode编码与utf-8 区别
    string的实现
  • 原文地址:https://www.cnblogs.com/birchtree/p/12391940.html
Copyright © 2020-2023  润新知