Mediocre String Problem(exkmp+manacher+差分

#include<bits/stdc++.h>
using namespace std;
const int N=2e6+10;
int Ma[N],Mp[N];
int cnt[N],to[N],cnt2[N];
void Manacher(char s[],int len){
    int l=0;
    Ma[l++]='$';
    Ma[l++]='#';
    for(int i=0;i<len;i++){
        to[l]=i;
        Ma[l++]=s[i];
        Ma[l++]='#';
    }
    Ma[l]=0;
    int mx=0,id=0;
    for(int i=0;i<l;i++){
        Mp[i]=mx>i?min(Mp[2*id-i],mx-i):1;
        while(Ma[i+Mp[i]]==Ma[i-Mp[i]]) Mp[i]++;
        if(i+Mp[i]>mx){
            mx=i+Mp[i];
            id=i;
        }
    }
    for(int i=2;i<2*len+2;i++){
        int len=Mp[i]-1;
        cnt[i]++;
        cnt[i+len+1]--;
    }
    for(int i=0;i<len*2+2;i++){
       cnt[i]+=cnt[i-1];
       if(i&&i%2==0){
            cnt2[i/2-1]=cnt[i];
       }
    }
    for(int i=len;i>=1;i--) cnt2[i]=cnt2[i-1];
    cnt2[0]=0;
}
int nxt[N],extend[N];
void preekmp(char x[],int m,int nxt[]){
    nxt[0]=m;
    int j=0;
    while(j+1<m&&x[j]==x[j+1]) j++;
    nxt[1]=j;
    int k=1;
    for(int i=2;i<m;i++){
        int p=nxt[k]+k-1;
        int L=nxt[i-k];
        if(i+L<p+1) nxt[i]=L;
        else{
            j=max(0,p-i+1);
            while(i+j<m&&x[i+j]==x[j]) j++;
            nxt[i]=j;
            k=i;
        }
    }
}
void ekmp(char x[],int m,char y[],int n,int nxt[],int extend[]){
    int j=0;
    while(j<n&&j<m&&x[j]==y[j]) j++;
    extend[0]=j;
    int k=0;
    for(int i=1;i<n;i++){
        int p=extend[k]+k-1;
        int L=nxt[i-k];
        if(i+L<p+1) extend[i]=L;
        else{
            j=max(0,p-i+1);
            while(i+j<n&&j<m&&y[i+j]==x[j]) j++;
            extend[i]=j;
            k=i;
        }
    }
    long long ans=0;
    for(int i=0;i<n;i++){
        ans+=(long long)extend[i]*(long long)cnt2[i];
    }
    cout<<ans<<endl;
}
char ch[N],t[N],k[N];
int main(){
    scanf("%s",ch);scanf("%s",t);
    int len=strlen(ch),len2=strlen(t);
    for(int i=0;i<len;i++) k[i]=ch[len-i-1];
    Manacher(k,len);
    preekmp(t,len2,nxt);
    ekmp(t,len2,k,len,nxt,extend);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值