Count the string

Problem 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 write down all the non-empty prefixes of this string. For example:
s: "abab"
The prefixes are: "a", "ab", "aba", "abab"
For
each prefix, we can count the times it matches in s. So we can see that
prefix "a" matches twice, "ab" matches twice too, "aba" matches once,
and "abab" matches once. Now you are asked to calculate the sum of the
match times for all the prefixes. For "abab", it is 2 + 2 + 1 + 1 = 6.
The answer may be very large, so output the answer mod 10007.
 
Input
The first line is a single integer T, indicating the number of test cases.
For
each case, the first line is an integer n (1 <= n <= 200000),
which is the length of string s. A line follows giving the string s. The
characters in the strings are all lower-case letters.
 
Output
For each case, output only one number: the sum of the match times for all the prefixes of s mod 10007.
 
Sample Input
1
4
abab
 
Sample Output
6
思路:(字符串从1开始)
1.可以直接套用kmp的getfail()来得到f[i],但是这里的f[i]并不是p[i] = p[f[i]],而是在第i位失配情况下从第i位退回到第f[i]位判断是否能配对;这样就需要一直f[i]在f[i] = p[f[i]]时累加,直至i到0结束;由于里面使用的是朴素的mp匹配,即并没有进行优化f[i],KMP的时间复杂度为O(n),但是在循环查找的过程中,由于每个点最坏的情况就是倒退到1,这样最坏的时间复杂度就为O(n^2),能在78ms内过纯属数据..太弱了
#include <bits/stdc++.h>
using namespace std;
#define mod 10007
const int maxn=2e5+;
int f[maxn];
char s[maxn];
void getfail(char *T)
{
int i=,j=,n=strlen(T+);f[]=;
while(i<n){
if(j==||T[i]==T[j])//确定当前位,给下一位一个机会
++i,++j,f[i]=j;
else
j=f[j];
}
}
int main()
{
int T,n;
cin>>T;
while(T--)
{
scanf("%d%s",&n,s+);
getfail(s);
int cnt=;
for(int i=;i<=n;i++){
int t=;
for(int j=i;j;j=f[j])
if(s[i]==s[j]) // 相等才累加;
++t;
cnt=(cnt+t)%mod;
}
cout<<cnt<<endl;
}
return ;
}

2.上面的是正版的KMP...对于每一个f[i]其实只是一个试探可能性,并不确定是否相等;那么我们就利用前面的相等的f[i]来确定与当前位相等的f[i],这样就不需要病了f[i]来找是否p[i] = p[f[i]]了,并且这是一个基础,即一个子结构。用一个数组记录下前一个p[f[i]]的前缀串,直接+1即可;

62ms,时间复杂度为O(n)

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+;
const int mod = ;
char p[N];
int f[N],dp[N];
void getfail()
{
int j=,n=strlen(p+);
f[]=;
for(int i = ;i <= n;i++){
while(j && p[j+] != p[i]) j = f[j];//确定当前位置是前面前缀串的最后一位;
if(p[i] == p[j+]) j++;
f[i] = j;
}
}
int main()
{
int n,T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
scanf("%s", p+);
getfail();
int ans = ;
dp[] = ;
for(int i = ;i <= n;i++){
dp[i] = dp[f[i]] + ;
ans = (ans+dp[i])%mod;
}
printf("%d\n",ans);
}
return ;
}

hdu 3336 Count the string KMP+DP优化的更多相关文章

  1. hdu 3336 Count the string -KMP&dp

    It is well known that AekdyCoin is good at string problems as well as number theory problems. When g ...

  2. [HDU 3336]Count the String[kmp][DP]

    题意: 求一个字符串的所有前缀串的匹配次数之和. 思路: 首先仔细思考: 前缀串匹配. n个位置, 以每一个位置为结尾, 就可以得到对应的一个前缀串. 对于一个前缀串, 我们需要计算它的匹配次数. k ...

  3. HDU 3336 Count the string ( KMP next函数的应用 + DP )

    dp[i]代表前i个字符组成的串中所有前缀出现的次数. dp[i] = dp[next[i]] + 1; 因为next函数的含义是str[1]~str[ next[i] ]等于str[ len-nex ...

  4. HDU 3336 Count the string KMP

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3336 如果你是ACMer,那么请点击看下 题意:求每一个的前缀在母串中出现次数的总和. AC代码: # ...

  5. HDU 3336 Count the string(KMP的Next数组应用+DP)

    Count the string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  6. hdu 3336:Count the string(数据结构,串,KMP算法)

    Count the string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. HDU 3336 Count the string(next数组运用)

    Count the string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  8. HDU 3336 Count the string 查找匹配字符串

    Count the string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  9. hdu 3336 count the string(KMP+dp)

    题意: 求给定字符串,包含的其前缀的数量. 分析: 就是求所有前缀在字符串出现的次数的和,可以用KMP的性质,以j结尾的串包含的串的数量,就是next[j]结尾串包含前缀的数量再加上自身是前缀,dp[ ...

随机推荐

  1. (手写识别) Zinnia库及其实现方法研究

    Zinnia库及其实现方法研究 (转) zinnia是一个开源的手写识别库.采用C++实现.具有手写识别,学习以及文字模型数据制作转换等功能. 项目地址 [http://zinnia.sourcefo ...

  2. iOS之开发程序之间的跳转及跳转到appStore

    实例一:A程序跳转到B程序 第一步: 在B程序plist文件中,注册对外接口如图在B程序中找到info.plist点击,找到Information Property List ,右击 添加列表项 找到 ...

  3. Enable HTTPS in Spring Boot

    Spring-boot-enable-ssl Enable HTTPS in Spring Boot APRIL 14, 2015DRISS AMRI This weekend I answered ...

  4. Matlab中tic和toc用法

    简单地说,tic和toc是用来记录matlab命令执行的时间 tic用来保存当前时间,而后使用toc来记录程序完成时间. 两者往往结合使用,用法如下: tic operations toc 显示时间单 ...

  5. JAXB - XML Schema Types, Binary Data

    Data that has no "natural" representation with printable characters must, for inclusion in ...

  6. WIN8+VS2013编写发布WCF之一(编写)

      引言:上学期因为写服务器用WCF,所以连查资料再瞎调试勉强成功了,但是这学期又到了用WCF的时候,而当时的资料零零散散,查找不易,并且此次是在WIN8与VS2013环境下编写的,所以将该入门过程记 ...

  7. 编写delegate(明天补充)

    delegate基本上是一种callback机制,让别的类在

  8. 三【相关度 相似度查询与计算】相似度到大数据查找之Mysql 文章匹配的一些思路与提高查询速度

    记录下,在上2回的数据基础之上,附带一个互信息(MI,Mutual Information)可以计算词之间的相关度 标准互信息 MI(X,Y)=log2p(x,y)/p(x)p(y) 值越大于0 则趋 ...

  9. SVG实现描边动画

    说起SVG,我是恨它又爱它,恨它是因为刚开始接触的时候自己傻B地想用代码去写它,其实在web上我们用它做交互也只是用了几个常用的特性而已,其他的标签知道这么一回事就成了,其实说白了它就是一种图片格式, ...

  10. 牛客网算法题之All-in-All

    题目: 有两个字符串s 和t,如果即从s 中删除一些字符,将剩余的字符连接起来,即可获得t.则称t是s 的子序列.请你开发一个程序,判断t是否是s的子序列. 输入描述: 输入包含多组数据,每组数据包含 ...