码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-02-08 13:03:50      阅读:244      评论:0      收藏:0      [点我收藏+]

标签:color   pre   math   spl   class   require   strong   hdu   nbsp   

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\n",ans);
    }
    return 0;
}

 

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

标签:color   pre   math   spl   class   require   strong   hdu   nbsp   

原文地址:https://www.cnblogs.com/hua-dong/p/10356058.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!