• Luogu P4287 [SHOI2011]双倍回文PAM


    多维护一个转移 (tra[p]),表示 (leq frac{len[p]}{2}) 的后缀位于的状态。

    最后检查一下是否有 (len[tra[p]]=len[p]/2 && len[tra[p]]\%2==0)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define R register int
    using namespace std;
    namespace Luitaryi {
    inline int g() { R x=0,f=1;
      register char s; while(!isdigit(s=getchar())) f=s=='-'?-1:f;
      do x=x*10+(s^48); while(isdigit(s=getchar())); return x*f;
    } const int N=100010;
    int n,tot,lst,ans;
    int fa[N],c[N][26],len[N],cnt[N],sz[N],tra[N];
    char s[N];
    inline int jmp(int p,int i) 
      {while(s[i-len[p]-1]!=s[i]) p=fa[p]; return p;}
    inline void add(int ch,int i) {
      R p=jmp(lst,i); if(!c[p][ch]) {
        R np=++tot; len[np]=len[p]+2;
        R t=jmp(fa[p],i);
        fa[np]=c[t][ch],c[p][ch]=np;
        if(len[np]<=2) tra[np]=fa[np];
        else {
          t=tra[p];
          while(s[i-len[t]-1]!=s[i]||(len[t]+2)*2>len[np]) t=fa[t];
          tra[np]=c[t][ch]; 
        }
      } lst=c[p][ch];
    }
    inline void main() {
      n=g(),scanf("%s",s+1);
      s[0]='#',len[fa[fa[1]=0]=tot=1]=-1;
      for(R i=1;i<=n;++i) add(s[i]-'a',i);
      for(R i=2;i<=tot;++i)
        if(len[tra[i]]*2==len[i]&&!(len[tra[i]]&1)) 
          ans=max(ans,len[i]);
      printf("%d
    ",ans);
    }
    } signed main() {Luitaryi::main(); return 0;}
    

    2020.01.16

  • 相关阅读:
    mysql第三天作业
    mysql第二天作业
    mysql第一天作业
    S5第一次月考
    网络编程(待补充)
    字符编码(待补充)
    继承和封装
    面向对象
    codeforces 394E Lightbulb for Minister 简单几何
    跟面试官讲Binder(零)
  • 原文地址:https://www.cnblogs.com/Jackpei/p/12202915.html
Copyright © 2020-2023  润新知