标签: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 1≤i≤j<k≤leng
aaa abcSample 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