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

    P4287 [SHOI2011]双倍回文

    题意

    给定一个字符串(S),求它的最长双倍回文子串长度,双倍回文串是一个回文串且它的前一半和后一半都是相同的偶回文串。

    (|S|le 5cdot 10^5)

    分析

    建回文自动机的过程中求出一个(trans)指针,(trans)指针的含义是小于等于当前节点长度一半的最长回文后缀,求出这个后直接冲就完事了。

    Code

    #include<bits/stdc++.h>
    #define mp make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define lson l,mid,p<<1
    #define rson mid+1,r,p<<1|1
    #define ll long long
    using namespace std;
    const int inf=1e9;
    const int mod=19930726;
    const int maxn=2e6+10;
    typedef pair<ll,ll> pii;
    char s[maxn];
    int n,now;
    ll k;
    ll ksm(ll a,ll b){
        ll ret=1;
        while(b){
            if(b&1) ret=ret*a%mod;
            b>>=1;
            a=a*a%mod;
        }
        return ret;
    }
    struct PAM{
        int son[maxn][26],fail[maxn],trans[maxn],len[maxn],tot,last;
        pii a[maxn];
        ll sz[maxn];
        int cnt;
        int newnode(int x){
            ++tot;
            for(int i=0;i<26;i++) son[tot][i]=0;
            fail[tot]=0;len[tot]=x;
            return tot;
        }
        void init(){
            tot=-1;newnode(0);newnode(-1);
            fail[0]=1;
            last=0;
        }
        int gao(int x){
            while(s[now-len[x]-1]!=s[now]) x=fail[x];
            return x;
        }
        void insert(){
            int p=gao(last);
            if(!son[p][s[now]-'a']){
                int tmp=son[gao(fail[p])][s[now]-'a'];
                son[p][s[now]-'a']=newnode(len[p]+2);
                fail[tot]=tmp;
                if(len[tot]<=2) trans[tot]=fail[tot];
                else{
                	tmp=trans[p];
                	while(s[now-len[tmp]-1]!=s[now]||(len[tmp]+2)*2>len[tot]) tmp=fail[tmp];
                	trans[tot]=son[tmp][s[now]-'a'];
                }
            }
            last=son[p][s[now]-'a'];
            sz[last]++;
        }
        int gao(){
            int ans=0;
            for(int i=1;i<=tot;i++){
            	int x=trans[i];
            	if(len[i]%2==0&&len[x]%2==0&&len[x]*2==len[i]) ans=max(ans,len[i]);
            }
            return ans;
        }
    }P;
    int main(){
        //ios::sync_with_stdio(false);
        //freopen("in","r",stdin);
        scanf("%d",&n);
        scanf("%s",s+1);
        s[0]='$';
        P.init();
        for(now=1;now<=n;now++){
            P.insert();
        }
        printf("%d
    ",P.gao());
        return 0;
    }
    
  • 相关阅读:
    Moq4在.NET3.5和.NET4版本之间的差异
    TDD中的迭代
    洛谷 3413 萌数
    割点(tarjan)
    hdu-4507 吉哥系列故事——恨7不成妻
    hdu-3709 Balanced Number
    poj-3252 Round Numbers
    hdu 1007 Quoit Design 分治求最近点对
    LA 3905 Meteor 扫描线
    uva 11464
  • 原文地址:https://www.cnblogs.com/xyq0220/p/14025701.html
Copyright © 2011-2022 走看看