Interesting
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 349 Accepted Submission(s): 121
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.
Each test case contains one string. The length of string is between 1 and 1000000. String only contains lowercase letter.
aaa abc
14 8
给出一个长度为n(n<=10^6)的串,对于0<i<=j<k<=n,如果s[i,j]和s[j+1,k]都是回文串,则答案加上i*k,最后答案模10^9+7。
在原串上,用L[i]表示以i开始的所有回文串结束位置的和,R[i]表示以i结尾的所有回文串起始位置的和,枚举位置i,每次将L[i]*R[i-1]加上答案即可。
import java.io.*;
import java.util.*;
public class Main {
static StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
static int n,len;
static long ans,mod=(long)1e9+7,s1,s2;
static char[] ss;
static int[] pp=new int[2000005];
static char[] s=new char[2000005];
static long[] bb1=new long[2000005];
static long[] bb2=new long[2000005];
static long[] ll=new long[1000005];
static long[] rr=new long[1000005];
static void Manacher()
{
Arrays.fill(s,'#');
for(int i=0;i<n;i++)
s[i*2+2]=ss[i];
len=n*2+1;s[0]='$';
int max=0,id=0;
for(int i=1;i<=len;i++)
{
if(max>i)
pp[i]=Math.min(pp[id*2-i],max-i);
else pp[i]=1;
while(s[i+pp[i]]==s[i-pp[i]])
pp[i]++;
if(i+pp[i]>max) { max=i+pp[i];id=i;}
}
}
public static void main(String[] args) throws IOException {
//Scanner in=new Scanner(System.in);
while(in.nextToken()!=StreamTokenizer.TT_EOF)
{
ss=in.sval.toCharArray();
n=ss.length;
Manacher();
Arrays.fill(bb1,0);
Arrays.fill(bb2,0);
for(int i=len;i>0;i--)
{
bb1[i-pp[i]+1]+=i;
bb1[i+1]-=i;
bb2[i-pp[i]+1]++;
bb2[i+1]--;
}
s1=s2=0;
for(int i=1;i<=len;i++)
{
s1+=bb1[i];s2+=bb2[i];
if(i%2==0)
ll[i/2]=(s1-s2*i/2)%mod;
}
Arrays.fill(bb1,0);
Arrays.fill(bb2,0);
for(int i=len;i>0;i--)
{
bb1[i]+=i;
bb1[i+pp[i]]-=i;
bb2[i]++;
bb2[i+pp[i]]--;
}
s1=s2=0;
for(int i=1;i<=len;i++)
{
s1+=bb1[i];s2+=bb2[i];
if(i%2==0)
rr[i/2]=(s1-s2*i/2)%mod;
}
ans=0;
for(int i=2;i<=n;i++)
ans=(ans+ll[i]*rr[i-1]%mod)%mod;
out.println(ans);
}
out.flush();
}
}
631



被折叠的 条评论
为什么被折叠?



