zoukankan      html  css  js  c++  java
  • bzoj2342 [Shoi2011]双倍回文

    建立回文树得出所有本质不同的回文串,用hash判断每个长度为偶数的回文串其双倍是否是原串的子串

    #include<cstdio>
    #include<algorithm>
    typedef unsigned long long u64;
    const int N=500005,P=293;
    u64 pp[N]={1},h[N],hs[N];
    int nx[N][26],fa[N],l[N],t[N],d[N],q[N],ql=0,qr=0,ptr=2,pv=2,len;
    char s[N];
    void ins(int w){
        int p=pv,x,c=s[w]-'a';
        while(1){
            x=w-1-l[p];
            if(x>=0&&s[w]==s[x])break;
            p=fa[p];
        }
        if(nx[p][c]){
            pv=nx[p][c];
            return;
        }
        pv=++ptr;
        l[pv]=l[p]+2;
        nx[p][c]=pv;
        if(!(l[pv]&1))h[pv]=h[p]*P+s[w]+s[w]*pp[l[pv]-1];
        if(l[pv]==1){
            fa[pv]=2;
            return;
        }
        while(1){
            p=fa[p];
            x=w-1-l[p];
            if(x>=0&&s[w]==s[x]){
                fa[pv]=nx[p][c];
                break;
            }
        }
    }
    int main(){
        l[1]=-1;
        fa[1]=fa[2]=1;
        scanf("%d%s",&len,s);
        for(int i=1;i<=len;i++)pp[i]=pp[i-1]*P;
        for(int i=0;i<len;i++)ins(i);
        for(int i=3;i<=ptr;i++)hs[i]=h[i];
        std::sort(hs+3,hs+ptr+1);
        int ans=0;
        for(int i=3;i<=ptr;i++){
            if(l[i]&1)continue;
            if(l[i]<ans)continue;
            u64 v=h[i]*pp[l[i]]+h[i];
            if(*std::lower_bound(hs+3,hs+ptr+1,v)==v)ans=l[i];
        }
        printf("%d",ans*2);
        return 0;
    }
  • 相关阅读:
    放大图 带回弹效果
    用recyclerview实现对话(通过接口实现)
    java 问号表达式
    recyclerview的使用
    我遇到的报错信息整理
    横竖屏切换
    NOIP 2017提高组自测 奶酪
    小蝌蚪找妈妈 牛客
    牛客练习赛50 C tokitsukaze and Soldier
    洛谷P1630 求和
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5493789.html
Copyright © 2011-2022 走看看