HUST 1328 String (字符串前缀子串个数 --- KMP)
题意
给定一个字符串S,定义子串subS[i] = S[0..i],定义C[i]为S中subS[i]的数量,求sigma(C[i])(0<=i<N)。
思路
我们以子串结尾的位置来划分阶段求解,即,设ans[i]表示以第i个字符为结尾的子串的个数,则res = sigma(ans[i])。
那么我们怎么求出以某个位置为结尾的字符串中有多少是subS[i]呢?
考虑subS[i]就是S的N个前缀,而以某个位置为结尾又是后缀,所以我们自然要想到利用next数组---前缀后缀对称来解决这个问题。
由next[i]=j表示S[1...j] = S[i-j+1...i]可知,以i为结尾的子串中包含subS[j]本身,并且,它一定还包含subS[j]所包含的前缀。所以ans[i] = ans[j]+1。
最后再加上以i为结尾的子串它本身(上面计算时并没有包括它本身)。
代码
[cpp]
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#define MID(x,y) ((x+y)/2)
#define MEM(a,b) memset(a,b,sizeof(a))
#define REP(i, begin, end) for (int i = begin; i <= end; i ++)
using namespace std;
char s[100005];
long long next[100005], res[100005], ans;
long long cal_res(int j){
if (next[j] == -1)
return 0;
else if (~res[j]){
return res[j];
}
else{
res[j] = cal_res(next[j]) + 1;
return res[j];
}
}
void get_next(){
int len = strlen(s), j = -1;
ans = len; next[0] = -1;
for (int i = 1; i < len; i ++){
while(j > -1 && s[i] != s[j+1]) j = next[j];
if (s[i] == s[j+1]) j ++;
next[i] = j;
ans += cal_res(i);
}
}
int main(){
int t;
scanf("%d", &t);
while(t --){
MEM(s, 0); MEM(res, -1);
scanf("%s", s);
get_next();
printf("%lld\n", ans);
}
return 0;
}
[/cpp]
HUST 1328 String (字符串前缀子串个数 --- KMP)的更多相关文章
- SPOJ - SUBST1 New Distinct Substrings —— 后缀数组 单个字符串的子串个数
题目链接:https://vjudge.net/problem/SPOJ-SUBST1 SUBST1 - New Distinct Substrings #suffix-array-8 Given a ...
- HUST 1328 String
11: KMP next 的强大 题意求前缀在S中出现的次数之和 next[j] 表示 S[0....NEXT[J]]==S[J-NEXT[J].....J]; 于是我们得到..后加入一个字符所得到新 ...
- C++ 字符串中子串个数
子串可重叠情况: int fun1(const std::string& str, const std::string& sub){ int num = 0; for (size_t ...
- C++自定义String字符串类,支持子串搜索
C++自定义String字符串类 实现了各种基本操作,包括重载+号实现String的拼接 findSubStr函数,也就是寻找目标串在String中的位置,用到了KMP字符串搜索算法. #includ ...
- HDU 4622 Reincarnation (查询一段字符串的不同子串个数,后缀自动机)
Reincarnation Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)To ...
- HDU4622 (查询一段字符串的不同子串个数,后缀自动机)
http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意:给出一个字符串和q次询问,每次询问[l,r]区间内不同子串的个数 分析: N<=2000. 我 ...
- HDU 3336 输出包括从1到len长 字符串前缀的总个数(+DP)
Sample Input14abab Sample Output6输出包括从1到len长 字符串前缀的总个数abab:包括2个a,2个ab,1个aba,1个abab # include <cst ...
- 给出一个string字符串,统计里面出现的字符个数
给出一个string字符串,统计里面出现的字符个数 解决方案: 使用algorithm里面的count函数,使用方法是count(begin,end,'c'),其中begin指的是起始地址,end指的 ...
- iOS - Swift String 字符串
前言 public struct String public class NSString : NSObject, NSCopying, NSMutableCopying, NSSecureCodin ...
随机推荐
- mysql中explain的用法
mysql中explain的用法 最近在做性能测试中经常遇到一些数据库的问题,通常使用慢查询日志可以找到执行效果比较差的sql,但是仅仅找到这些sql是不行的,我们需要协助开发人员分析问题所在,这就经 ...
- 2017 Multi-University Training Contest - Team 4 hdu6071 Lazy Running
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6071 题目: Lazy Running Time Limit: 2000/1000 MS (J ...
- Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals) D. Innokenty and a Football League
地址:http://codeforces.com/contest/782/problem/D 题目: D. Innokenty and a Football League time limit per ...
- [转]DNS服务器原理详解与Centos6.x下搭建DNS服务器
转自:http://blog.it985.com/8958.html DNS 数据库的记录:正解,反解, Zone 的意义 通过DNS解析过程详解这篇文章,我们知道了要想访问www.zmit.cn,最 ...
- Java linkedList详细介绍及使用示例
①LinkedList简单介绍 是一个继承于AbstractSequentialList的双向链表.它可以被当成堆栈.队列或双端队列进行操作. 实现了List接口,能对它进行队列操作. 实现了Dequ ...
- 20145316许心远《Java程序设计》第4周学习总结
20145316许心远<Java程序设计>第4周学习总结 教材学习内容总结 6.继承与多态 1.继承共同行为 * 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需 ...
- virtualbox安装centos7使用nat+hostonly的网络模式
win环境下的virtualbox下载地址:http://download.virtualbox.org/virtualbox/5.2.0/VirtualBox-5.2.0-118431-Win.ex ...
- 20145324 《Java程序设计》第6周学习总结
20145324 <Java程序设计>第6周学习总结 教材学习内容总结 第十章 1.使用输入串流将数据从来源取出 InputStream 使用输出串流将数据写入目的地 OutStream ...
- Centos6优化系统服务脚本
#!/bin/bash SysVer=`cat /etc/redhat-release | awk -F'release' '{print $2}' | awk -F'[ .]+' '{print $ ...
- SpringBoot 打包为Docker进行
可以有两种方式: 1.dockerfile 2.maven docker 第一种方式:通过dockerfile打包Docker镜像 1.将dockerfile和 springboot打包的jar文件放 ...