Mediocre String Problem
问题 M: Mediocre String Problem
时间限制: 1 Sec 内存限制: 128 MB提交: 18 解决: 4
[提交] [状态] [命题人:admin]
题目描述
Given two strings s and t, count the number of tuples (i, j, k) such that
1. 1 ≤ i ≤ j ≤ |s|
2. 1 ≤ k ≤ |t|.
3. j − i + 1 > k.
4. The i-th character of s to the j-th character of s, concatenated with the first character of t to the k-th character of t, is a palindrome.
A palindrome is a string which reads the same backward as forward, such as “abcba” or “xyzzyx”.
1. 1 ≤ i ≤ j ≤ |s|
2. 1 ≤ k ≤ |t|.
3. j − i + 1 > k.
4. The i-th character of s to the j-th character of s, concatenated with the first character of t to the k-th character of t, is a palindrome.
A palindrome is a string which reads the same backward as forward, such as “abcba” or “xyzzyx”.
输入
The first line is the string s (2 ≤ |s| ≤ 106 ). The second line is the string t (1 ≤ |t| < |s|). Both s and t contain only lower case Latin letters.
输出
The number of such tuples.
样例输入
ababa
aba
样例输出
5
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=3e6+10; const int N=206; const int M=28; const ll mod=1e9+7; char str[maxn]; char S[maxn]; ll len_S,len_T,radius[maxn]; char e[maxn]; int nx[maxn]; ll extend[maxn]; inline void pre_EX_kmp(){ nx[0]=len_T; int j=0; while(j+1<len_T&&S[j]==S[j+1])++j; nx[1]=j; int cur=1; for(register int i=2;i<len_T;++i){ int p=nx[cur]+cur-1; int L=nx[i-cur]; if(i+L<p+1){ nx[i]=L; } else{ int f=max(0,p-i+1); while(i+f<len_T&&S[i+f]==S[f])++f; nx[i]=f; cur=i; } } /*for(register int i=0;i<len_T;++i){ printf("%d ",nx[i]); } printf("\n");*/ } //ababa //aba inline void EX_kmp(){ int j=0; while(j<len_S&&j<len_T&&str[j]==S[j])++j; extend[0]=j; int k=0; for(register int i=1;i<len_S;++i){ int p=extend[k]+k-1; int L=nx[i-k]; if(i+L<p+1){ extend[i]=L; } else{ int f=max(0,p-i+1); while(i+f<len_S&&f<len_T&&str[i+f]==S[f])++f; extend[i]=f; k=i; } } // for(register int i=0;i<len_S;++i){ // printf("%d ",extend[i]); // } // printf("\n"); } inline void Manacher(){ int len=0; e[len++]='$'; e[len++]='#'; for(register int i=0;i<len_S;++i){ e[len++]=str[i]; e[len++]='#'; } e[len]=0; ll mx=0,id=0; for(register int i=0;i<len;++i){ radius[i]=mx>i?min(mx-i,radius[2*id-i]):1; while(e[i-radius[i]]==e[i+radius[i]])++radius[i]; if(i+radius[i]>mx){ mx=i+radius[i]; id=i; } //printf("debug radiu[%d] = %d\n",radius[i]); } } int o[maxn]; int main() { #ifndef ONLINE_JUDGE freopen("1.txt","r",stdin); #endif scanf("%s",str); len_S=strlen(str); //printf("debug len_S = %d\n",len_S); reverse(str,str+len_S); scanf("%s",S); len_T=strlen(S); pre_EX_kmp(); EX_kmp(); Manacher(); for(register int i=2;i<2*len_S+2;++i){ int R=radius[i]/2; if(i&1){ ++o[i/2+1]; --o[i/2+1+R]; } else{ ++o[i/2]; --o[i/2+R]; } } for(register int i=1;i<=len_S;++i)o[i]+=o[i-1]; ll res=0; for(register int i=1;i<len_S;++i){ res+=extend[i]*o[i]; } printf("%lld\n",res); return 0; }