Palindromic Tree

struct PalindromicTree
{
    static const int __=1e5+5;
    static const int alp=26;

    static int to_idx(char ch)
    {
        return ch-'a'+1;
    }

#define fail(x) t[x].nex[0]

    struct node
    {
        int len,times,dep,nex[alp+1];
        void set(int l,int fa,int d)
        {
            len=l,nex[0]=fa,dep=d;
        }
        void clear()
        {
            len=times=0;
            mem(nex,0);
        }
    }t[__];

    char s[__<<1];

    int idx,pre,saf,l,r;

    PalindromicTree() {clear();}

    void push_back(char c)
    {
        s[++r]=c;
        for(int x;x=r-t[saf].len-1;saf=fail(saf))
            if(x>=l && s[x]==s[r])break;
        int k=to_idx(s[r]);
        if(t[saf].nex[k])saf=t[saf].nex[k];
        else
        {
            int y=fail(saf);
            for(int x;x=r-t[y].len-1;y=fail(y))
                if(x>=l && s[x]==s[r])break;
            y=t[y].nex[k];
            t[++idx].clear();
            t[idx].set(t[saf].len+2,y,t[y].dep+1);
            t[saf].nex[k]=idx,saf=idx;
        }
        if(t[saf].len==r-l+1)pre=saf;
        ++t[saf].times;
        ans+=t[saf].dep;
    }

    void push_front(char c)
    {
        s[--l]=c;
        for(int x;x=l+t[pre].len+1;pre=fail(pre))
            if(x<=r && s[x]==s[l])break;
        int k=to_idx(s[l]);
        if(t[pre].nex[k])pre=t[pre].nex[k];
        else
        {
            int y=fail(pre);
            for(int x;x=l+t[y].len+1;y=fail(y))
                if(x<=r && s[x]==s[l])break;
            y=t[y].nex[k];
            t[++idx].clear();
            t[idx].set(t[pre].len+2,y,t[y].dep+1);
            t[pre].nex[k]=idx,pre=idx;
        }
        if(t[pre].len==r-l+1)saf=pre;
        ++t[pre].times;
        ans+=t[pre].dep;
    }

    ll solve()
    {
        ll ans=0;
        for(int i=idx;i>=2;--i)
        {
            t[fail(i)].times+=t[i].times;
            ans=max(ans,1ll*t[i].times*t[i].len);
        }
        return ans;
    }

    void clear()
    {
        idx=1,pre=saf=0,l=__,r=l-1;
        t[0].clear(),t[1].clear();
        t[0].set(0,1,0),t[1].set(-1,1,0);
    }
}PT;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容