HDU Count the string (KMP)

题面见http://acm.hdu.edu.cn/showproblem.php?pid=3336

给你一个字符串,让你找它的前缀在整个字符串出现的次数。

作为一个不会思考的笨比,直接用kmp去一个个计数,果不其然,t了

找了博客来看,大概就是kmp+dp,要用到kmp中的pret数组(有的人习惯叫next数组,知道就行)

dp的方程形式很简单,但很难理解。

这是原博主的原话:

如果用dp[i]表示该字符串前i个字符中出现任意以第i个字符结尾的前缀的次数,它的递推式是 dp[i]=dp[pret[i]]+1,

即以第i个字符结尾的前缀数等于以第pret[i]个字符为结尾的前缀数加上它自己本身,这里要好好理解一下,不太好解释

这个好好理解就很灵性了,orz。

仔细看dp[i]代表的含义,以第i个字符结尾的前缀,那么dp[pret[i]]代表什么呢,以第pret[i]结尾的前缀,(pret[i]的字符和i的字符是一样的)

那么dp[i]和dp[pret[i]]唯一不同的是什么呢?再看刚开始的那句话,dp[i]代表的含义,以第i个字符结尾的前缀,答案就很明显了,虽然它们结尾的字符是一样的

但dp[i]多了一个它自己本身,于是就有了那个dp方程。

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define INF 0x7fffffffffffffff

typedef long long ll;
const double PI=3.1415926535897931;
const long long mod=1e9+7;
const int MA= 1e7+10;
const int ma= 2*1e5+10;
const int few=1e3+10;
const int maxn=1e8+10;
using namespace std;
//////////////////////////////////////////////
string a;
int pret[ma];
int n;
int dp[ma];
void pre()
{
    int i = 0,len = -1;
    pret[0]=-1;
    while (i < n)
    {
        if(len == -1||a[i]==a[len])
        {
            i++;
            len++;
            pret[i] = len;
        }
        else
        {
            len = pret[len];
        }
    }
    return ;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n;
        cin>>a;
        pre();
        ll ans=0;
        dp[0]=0;
        for(int i=1; i<=n; i++)
        {
            dp[i]=dp[pret[i]]+1;
            cout<<"dp["<<i<<"]="<<dp[i]<<endl;
            dp[i]%=10007;
            ans=(ans+dp[i])%10007;
        }
        cout<<ans<<endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Aracne/p/12601805.html

时间: 2024-10-09 18:55:58

HDU Count the string (KMP)的相关文章

HDUOJ------3336 Count the string(kmp)

D - Count the string Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description It is well known that AekdyCoin is good at string problems as well as number theory problems. When given a string s, we can wr

HDU 3336 Count the string (KMP next数组运用——统计前缀出现次数)

Count the string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6375    Accepted Submission(s): 2947 Problem Description It is well known that AekdyCoin is good at string problems as well as nu

hdu 3336 Count the string KMP+DP

Count the string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6375    Accepted Submission(s): 2947 Problem Description It is well known that AekdyCoin is good at string problems as well as n

hud 3336 count the string (KMP)

这道题本来想对了,可是因为hdu对pascal语言的限制是我认为自己想错了,结果一看题解发现自己对了-- 题意:给以字符串 计算出以前i个字符为前缀的字符中 在主串中出现的次数和 如: num(abab)=num(a)+num(ab)+num(aba)+num(abab)=2+2+1+1=6; 题解:next[i]记录的是 长度为i 不为自身的最大首尾重复子串长度  num[i]记录长度为next[i]的前缀所重复出现的次数 附上代码: const mo=10007; var sum,next:

Count the string kmp

问题描述众所周知,aekdycoin擅长字符串问题和数论问题.当给定一个字符串s时,我们可以写下该字符串的所有非空前缀.例如:S:“ABAB”前缀是:“A”.“AB”.“ABA”.“ABAB”对于每个前缀,我们可以计算它在s中匹配的次数,因此我们可以看到前缀“a”匹配两次,“ab”也匹配两次,“ab a”匹配一次,“ab ab”匹配一次.现在,您需要计算所有前缀的匹配时间之和.对于“abab”,它是2+2+1+1=6.答案可能非常大,因此输出答案mod 10007. 输入第一行是一个整数t,表示

[HDU3336]Count the string(KMP+DP)

Solution 不稳定的传送门 对KMP的灵活应用 设dp[i]表示前[1,i]的答案 那么dp[i]=dp[p[i]]+1,p[i]为失配函数 Code #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int mo=10007; int n,T,dp[200010],p[200010],Ans; char s[200010]; int main(

HDU Count the string+Next数组测试函数

链接:http://www.cnblogs.com/jackge/archive/2013/04/20/3032942.html 题意:给定一字符串,求它所有的前缀出现的次数的和.这题很纠结,一开始不知道怎么做,如果直接统计子串在主串中出现的次数,orz···肯定 TLE,后来发现这题可以直接从next数组入手,因为next数组表示的是子串中最长公共前后缀串的长度,如果用dt[i]表示该字符串前i个字符中出 现任意以第i个字符结尾的前缀的次数,它的递推式是 dt[i]=d[next[i]]+1,

hdu 3336 Count the string(KMP)

一道应用kmp算法中next数组的题目 这其中vis[i]从1加到n vis[i]=[next[i]]+1; #include<string.h> #include<stdlib.h> #include<stdio.h> #include<iostream> #include<algorithm> using namespace std; char s[200005]; int b; int next[200005]; int vis[20000

[kuangbin带你飞]专题十六 KMP &amp; 扩展KMP &amp; ManacherK - Count the string HDU - 3336(前缀数量问题)

K - Count the string HDU - 3336 题目链接:https://vjudge.net/contest/70325#problem/K 题目: It is well known that AekdyCoin is good at string problems as well as number theory problems. When given a string s, we can write down all the non-empty prefixes of t