protagonist

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”.

 

输入

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;
}

 

posted @ 2019-10-05 19:51  czy-power  阅读(390)  评论(0编辑  收藏  举报