[2019牛客多校训练第6场]Palindrome Mouse

链接:https://ac.nowcoder.com/acm/contest/886/C
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
分数:2800

题目描述
Doctor has a string s s consisting of only lowercase letters. Doctor has got the set of all palindromic substrings of a string s s , denoted by the set S S . Now, he wants to choose two distinct strings a a and b b from the set S S which satisfy that the string a is a a substring of the string b b . How many different pairs ( a a , b b ) can Doctor choose?
输入描述:

There are multiple test cases. The first line contains an integer T ( 1 T 5 ) T(1 \leq T \leq 5) , indicating the number of test cases. Test cases are given in the following.

Each test case consists of only one line, containing a non-empty string s s ( 1 s 100000 1 \leq |s| \leq 100000 ), consisting of only lowercase letters.

输出描述:

For each test case, output “Case #x: y” in one line (without quotes), where x indicates the case number starting from 1, and y denotes the answer to this test case.

示例1
输入

4
aaaa
abba
abacaba
abc

输出

Case #1: 6
Case #2: 4
Case #3: 14
Case #4: 0

题意:
给定一个字符串 s s ,设其所有本质不同的回文子串组成的集合为 S S ,问有多少对 ( a , b ) (a,b) 满足 ( a , b S ) (a,b \in S) a a b b 的子串

题解:
果然对回文自动机的各个标签表示还是不够熟悉啊…
由于我们知道,如果 f a [ u ] = v fa[u]=v 那么 v v 就是 u u 的一个真子回文串。
我们从回文树的两个节点开始dfs。
那么我们对于每一个回文串 x x 统计所有合法的(长度大于等于1的) f a [ x ] fa[x] , f a [ f a [ x ] ] fa[fa[x]] , f a [ f a [ f a [ x ] ] ] . . . . . fa[fa[fa[x]]]..... 的数量 c o [ x ] co[x] 和他的所有后继节点的回文串数量 b o [ x ] bo[x]
然后接下去进入下一个节点,进行相同的操作。
记住每个节点只能被统计一次,也只能被计算一次。
最后计算 ( b o [ i ] c o [ i ] ) (\sum bo[i]*co[i]) - 本质不同回文串总数 即可。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN=400004;
const int D=27;
char s[MAXN];
int l;
struct PAM{
    int cnt,last;
    ll ans;
    int fa[MAXN],len[MAXN],ch[MAXN][D],co[MAXN],bo[MAXN],vis[MAXN];
    int create(int Len,int Fa){
        len[cnt]=Len;
        fa[cnt]=Fa;
        return cnt++;
    }
    void CLEAR(){
        memset(vis,-1,sizeof(vis));
        for(int i=0;i<cnt;i++){
            len[i]=0;fa[i]=0;
            memset(ch[i],0,sizeof(ch[i]));
        }
        last=0;cnt=0;
        create(0,1);
        create(-1,0);
        ans=0;
    }
    int getfail(int p,int n){
        for(;s[n-len[p]-1]!=s[n];p=fa[p]);
        return p;
    }
    int add(int c,int pos){
        int p=getfail(last,pos);
        if(!ch[p][c]){
            ch[p][c]=create(len[p]+2,ch[getfail(fa[p],pos)][c]);
        }
        last=ch[p][c];
        return last;
    }
    int dfs(int x){
        bo[x]=1;
        co[x]=0;
        for(int i=x;i>1;i=fa[i]){
            if(vis[i]!=-1)break;
            vis[i]=x;
            co[x]++;
        }
        for(int i=0;i<26;i++){
            if(ch[x][i]){
                bo[x]+=dfs(ch[x][i]);
            }
        }
        for(int i=x;i>1;i=fa[i]){
            if(vis[i]!=x)break;
            vis[i]=-1;
        }
        return bo[x];
    }
    ll getans(){
        ans=0;
        dfs(1);
        dfs(0);
        for(int i=2;i<cnt;i++){
            ans+=1LL*bo[i]*co[i];
        }
        return ans-cnt+2;
    }
}pam;
int w33ha(int CASE){
    scanf("%s",s+1);
    l=strlen(s+1);
    pam.CLEAR();
    for(int i=1;i<=l;i++){
        pam.add(s[i]-'a',i);
    }
    printf("Case #%d: %lld\n",CASE,pam.getans());
    return 0;
}
int main(){
    int T;scanf("%d",&T);
    for(int i=1;i<=T;i++)w33ha(i);
    return 0;
}
发布了302 篇原创文章 · 获赞 19 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/dxyinme/article/details/98439852