HDU - 5785:Interesting (回文树,求相邻双回文的乘积)

Posted hua-dong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU - 5785:Interesting (回文树,求相邻双回文的乘积)相关的知识,希望对你有一定的参考价值。

Alice get a string S. She thinks palindrome string is interesting. Now she wanna know how many three tuple (i,j,k) satisfy 1ij<klength(S)

, S[i..j] and S[j+1..k] are all palindrome strings. It‘s easy for her. She wants to know the sum of i*k of all required three tuples. She can‘t solve it. So can you help her? The answer may be very large, please output the answer mod 1000000007.

A palindrome string is a string that is same when the string is read from left to right as when the string is read from right to left.
InputThe input contains multiple test cases.

Each test case contains one string. The length of string is between 1 and 1000000. String only contains lowercase letter.OutputFor each test case output the answer mod 1000000007.Sample Input
aaa
abc
Sample Output
14
8

题意:累计i*k的和,如果[i,j],[j+1,k]都是回文串;

思路:统计以j为结尾的回文串个数numj,以及他们的长度和addj; 以j+1为首....;那么这个位置的贡献就是(numj*(j+1)-addj)*(numj+1*j+addj+1);

此题要节约空间,所以不要开longlong的数组。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rep2(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int maxn=1000002;
const int Mod=1e9+7;
struct PAT
{
    struct node{
        int len,num,fail,son[26],add;
    }t[maxn];
    int last,n,tot,s[maxn];
    void init()
    {
        memset(t,0,sizeof(t));
        tot=last=1; n=0;
        t[0].len=0; t[1].len=-1;
        t[0].fail=t[1].fail=1;
        s[0]=-1;
    }
    void add(int c){
        int p=last; s[++n]=c;
        while(s[n]!=s[n-1-t[p].len]) p=t[p].fail;
        if(!t[p].son[c]){
            int v=++tot,k=t[p].fail;
            while(s[n]!=s[n-t[k].len-1]) k=t[k].fail;
            t[v].fail=t[k].son[c];
            t[v].len=t[p].len+2;
            t[v].num=t[t[v].fail].num+1;
            t[v].add=(t[t[v].fail].add+t[v].len)%Mod;
            t[p].son[c]=v;
        }
        last=t[p].son[c];
    }
}T;
int ans,sum[maxn];char c[maxn];
int main()
{
    while(~scanf("%s",c+1)){
        int N=strlen(c+1);
        T.init(); ans=0;
        rep(i,1,N) {
            T.add(c[i]-a);
            sum[i]=(1LL*T.t[T.last].num*(i+1)-T.t[T.last].add)%Mod;
        }
        T.init();
        rep2(i,N,1){
            T.add(c[i]-a);
            ans+=(ll)(T.t[T.last].add+1LL*T.t[T.last].num*(i-1)%Mod)*sum[i-1]%Mod;
            ans%=Mod;
        }
        printf("%d
",ans);
    }
    return 0;
}

 

以上是关于HDU - 5785:Interesting (回文树,求相邻双回文的乘积)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 5785 Function 倍增 (2016 ACM/ICPC Asia Regional Dalian Online)

Interesting Housing Problem HDU - 2426 (KM)

HDU 5323 SOLVE THIS INTERESTING PROBLEM 爆搜

hdu 2814 Interesting Fibonacci

hdu 3304 Interesting Yang Yui Triangle

HDU 2426 Interesting Housing Problem(二分图最佳匹配)