More than 2019 cattle off summer school camp (sixth) Palindrome Mouse palindrome tree + dfs

Topic Portal

The meaning of problems: Given a string, the string will be all put a palindromic substrings of all the collection, after deduplication. Q There are several pairs of this collection <a, b>, that is a substring of b.

Ideas: a partial began to think, and that number is only required for each suffix palindrome palindrome string of characters plus the number of beginning and end can be removed. In fact, if we get rid of the two-character string called a parent, then the parent node palindrome suffix and it could form such a pair.

  Contribution to set up a string x can produce for $ dp [x] $, we consider what contribution can produce x is it?

  One and all palindromes suffix itself combined contribution generated, this can be done by jumping fail palindrome tree.

  And is a combination of its own parent, this value is only 1, and requires the parent node is not 0 or 1, of course, and he can not be 0 or 1.

  There is also a contribution to the parent can produce, this is taken into account palindrome suffix the parent's parent and their own as well as parent and their own here can be obtained by dfs.

  A substring may also be their ancestors and node palindrome suffix, this case you want to mark it, can not double counting, such as $ aaa $. If kept out fail, it will jump to the last character $ a $, but $ a $ is also their parent.

 

#pragma GCC optimize (2)
#pragma G++ optimize (2)
#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
#include<cstdio>
#include<vector>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,b,a) for(int i=b;i>=a;i--)
#define clr(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pii pair<int,int >
using namespace std;
typedef long long ll;
ll rd()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int maxn=200010;
char s[maxn];
ll dp[maxn];
int vis[maxn],cat=1;
struct Palindromic_Tree
{
    struct Node
    {
        int son[26];
        int ff,len;
    }t[maxn];
    int last,tot;
    ll ans=0;
    void init()
    {
        memset(t,0,sizeof(t[0])*(tot+1));
        tot=last=ans=0;
        t[++tot].len=-1;
        t[0].ff=t[1].ff=1;
    }
    void extend(int c,int n)
    {
        int p=last;
        while(s[n-t[p].len-1]!=s[n])p=t[p].ff;
        if(!t[p].son[c])
        {
            int v=++tot,k=t[p].ff;
            t[v].len=t[p].len+2;
            while(s[n-t[k].len-1]!=s[n])k=t[k].ff;
            t[v].ff=t[k].son[c];
            t[p].son[c]=v;
        }
        last=t[p].son[c];
    }
    void dfs(int x,int fa){
        ll cnt=0;
        int cx=t[x].ff;
        vis[x]++;
        while(cx!=0&&cx!=1&&vis[cx]==0){vis[cx]++;cnt++;cx=t[cx].ff;
        }
        dp[x]=cnt;
        if(x!=0&&x!=1&&fa!=0&&fa!=1)dp[x]=dp[fa]+cnt+1;
        ans+=dp[x];
        rep(i,0,25){
            if(t[x].son[i])dfs(t[x].son[i],x);
        }
        vis[x]--;
        cx=t[x].ff;
        while(cnt--){
            vis[cx]--;cx=t[cx].ff;
        }
    }

    void solve(){
        dfs(1,1),dfs(0,1);
        printf("Case #%d: %lld\n",cat++,ans);
    }
}a;
int main(){
    int T;
    cin>>T;
    while(T--){
        scanf("%s",s+1);
        int len=strlen(s+1);
        a.init();
        rep(i,1,len){
            a.extend(s[i]-'a',i);
        }
        a.solve();
    }

}

 

Guess you like

Origin www.cnblogs.com/mountaink/p/11566624.html