1. 程式人生 > >HDU - 5785:Interesting (回文樹,求相鄰雙回文的乘積)

HDU - 5785:Interesting (回文樹,求相鄰雙回文的乘積)

mathjax code multiple ins lse ini har swe etc

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 (回文樹,求相鄰雙回文的乘積)