首页 > 其他分享 >A Secret HDU - 6153 扩展KMP || KMP

A Secret HDU - 6153 扩展KMP || KMP

时间:2022-09-05 20:23:01浏览次数:88  
标签:cnt 前缀 extend int Secret 6153 KMP 长度

题目链接:https://vjudge.net/problem/HDU-6153
题意
求一个串T的所有后缀在串S中出现的次数 ,最后再求和。

扩展KMP解法

可以利用拓展KMP求出S的每一个后缀和T的最长公共前缀。
假如当前最长公共前缀为k,就说明长度为k的前缀在S中出现了一次,并且这个k前缀不能构成k+1前缀。用一个cnt数组将各种长度前缀出现的次数记录下来。

对于样例2

abababab
aba

首先将样例翻转,得到

babababa
aba

拓展KMP求出的extend数组值如下

extend[0] = 0
extend[1] = 3
extend[2] = 0
extend[3] = 3
extend[4] = 0
extend[5] = 3
extend[6] = 0
extend[7] = 1

所以cnt数组值为

cnt[1] = 1
cnt[2] = 0
cnt[3] = 3

根据cnt数组来求T的前缀在S中出现的次数:

  • 长度为3的前缀:出现了3次不解释。

  • 长度为2的前缀:在长度为3的前缀中出现过3次,不能构成3前缀的2前缀数目(即cnt[2])等于0,所以2前缀出现了3次。

  • 长度为1的前缀:在长度为2的前缀中出现了3次,不能构成2前缀的1前缀数目(即cnt[1])等于1,所以1前缀出现了4次。

问题解决

代码


KMP解法

KMP:和拓展KMP相似。
主要思路就是求出不能构成k + 1前缀的k前缀数目。
用KMP统计T串在S串中出现次数 的代码相似,KMP匹配的时候,我们只需要在失配和匹配完成的时候记录一下即可。
设失配的时候已经匹配的长度为k,那么这个k前缀不能构成k + 1前缀。

代码

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define ll long long
const int N=1e6+5;
int n,m,nextval[N];
char s[N],t[N];
ll id[N];
const int mod=1e9+7;
void getNextval()
{
    int i=0,j=-1;
    nextval[0]=-1;
    while(i<m)
    {
        if(j==-1||t[i]==t[j])
            nextval[++i]=++j;
        else j=nextval[j];
    }
}
void KMP()
{
    getNextval();
    int i=0,j=0;
    while(i<n)
    {
        if(j==-1||s[i]==t[j]) ++i,++j;
        else j=nextval[j];
        id[j]++;
        if(j==m)
            j=nextval[j];
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(id,0,sizeof(id));
        scanf("%s%s",s,t);
        n=strlen(s),m=strlen(t);
        for(int i=0; i<=(n-1)/2; ++i)
            swap(s[i],s[n-1-i]);
        for(int i=0; i<=(m-1)/2; ++i)
            swap(t[i],t[m-1-i]);
        KMP();
        ll ans=0;
        for(int i=m; i>0; --i)
        {
            id[nextval[i]]+=id[i];
            ans=(ans+id[i]*i)%mod;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

原文:
https://blog.csdn.net/ECNU_LZJ/article/details/77477204

标签:cnt,前缀,extend,int,Secret,6153,KMP,长度
From: https://www.cnblogs.com/kingwz/p/16659436.html

相关文章

  • “CSS Secret”——47 种 CSS 必备技能(第 1 部分 0-19)
    我正在参加第6期掘金创想营,点击了解活动详情前言《CSSDemystification》一书以案例的形式介绍了47个经典网页设计问题的解决方案。学习后我一一记录下来,方便复习。本......
  • luoguP8085 [COCI2011-2012#4] KRIPTOGRAM 题解(KMP)
    /*给定明文和密文,密文与明文的某个字串格式相同,找出密文出现的最早位置。如:明文aaabcdabc 密文xy ans:3解:容易想到KMP算法。可以发现,密文和对应子串的格式相同......
  • KMP自动机例题(待学习)
    KMP自动机可以在O(1)的时间内计算kmp。KMP自动机数组kmp_auto[i][j]可以表示第i位为'a'+j时的最长前缀长度(此前缀可以包含自身)。kmp[i]数组,表示第i位的最长前缀长度(不含......
  • OneSecretTwoEncryption ACTF2018
    InvolvedKnowledgeRSASharedprimenumberTopicpublic1.pub-----BEGINPUBLICKEY-----MIICIDANBgkqhkiG9w0BAQEFAAOCAg0AMIICCAKCAQAma/gXML+bivU20mJu55PZSjNA......
  • KMP算法学习记录
    KMP算法作用:用于字符串匹配。1准备前缀:指不包含最后一个字符的所有以第一个字符开头的连续子串。后缀:指不包含第一个字符的所有以最后一个字符结尾的连续子串。next[......
  • KMP
    字符串匹配算法时间复杂度O(n+m)#include<bits/stdc++.h>usingnamespacestd;#definelllonglong#defineendl"\n"#definesfscanf#definepfprintf#define......
  • KMP算法——深入骨髓的领悟
    前缀函数与KMP算法真前缀:S中不全等于S的前缀前缀函数定义\(s[0\dotsi]\)的真前缀与真后缀相等的最大长度为\(\pi(i)\)。规定\(\pi(0)=0\)。计算前缀函数1.朴......
  • 扩展kmp
    扩展kmp扩展kmp处理的问题:字符串S和字符串T,求S的每个后缀与T的最长公共前缀nxt数组与kmp的不一样charS[N],T[N];intn,m,nxt[N],extend[N];//nxt[i]表示从T[i......
  • kubernetes之镜像拉取策略ImagePullSecrets;
    1.容器镜像是什么?1.容器镜像(ContainerImage)是最终运行的软件;2.容器镜像(最初为Docker镜像,现在叫OCI镜像更合适)是将软件打包的形式。但是容器镜像还可以携带额外的设......
  • KMP
    KMP字符串基本概念字符串S:无特殊说明,字符串仅由26个小写字母'a'-'z',并用大写字母表示一个字符串 S="abcd"|S|:表示一个字符串的长度 |S|=4S[i]:表示字符串S第i个......