zoukankan      html  css  js  c++  java
  • 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("
    ");*/
    }
    //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("
    ");
    }
    
    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
    ",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
    ",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
    ",res);
        return 0;
    }
  • 相关阅读:
    Lombok 安装、入门
    Centos 6.5中使用yum安装jdk
    Mysql规范和使用注意点(转)
    Java编码规范
    windows2016重新配置sid
    Postman POST接口请求无法获取数据
    微信修改密码
    SQL事务
    .net时间格式化
    SQL查询列是否有重复值
  • 原文地址:https://www.cnblogs.com/czy-power/p/11625563.html
Copyright © 2011-2022 走看看