【后缀数组】【LuoguP2408】 不同子串个数
题目描述
给你一个长为N的字符串,求不同的子串的个数
我们定义两个子串不同,当且仅当有这两个子串长度不一样 或者长度一样且有任意一位不一样。
子串的定义:原字符串中连续的一段字符组成的字符串
说明
对于100%的数据,N≤10^5
思路
能发现任何一个子串都是某一个后缀的前缀
实际上就是求所有后缀有多少本质不同的前缀
我们考虑按照将所有后缀按照字典序排序,那么每次新加进来的一个后缀的前缀的个数为 \(n-sa[i]+1\),但是与前面重复的前缀有 \(H[i]\) 个
因为对于 \(sa[i]\),它与前面的所有后缀的最长公共前缀就是它与 \(sa[i-1]\) 的最长公共前缀,所以重复的前缀有 \(H[i]\) 个
我们把后缀 \(sa[i ]\) 和后缀 \(sa[i - 1]\) 公共前缀看成是 \(i-1\) 所独有的子串,那么答案就是 \(\sum_{i}n-sa[i]+1-H[i]\)
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 1000010
#define ll long long
using namespace std;
int n;
char s[maxn];
int tax[maxn], tp[maxn], sa[maxn], rk[maxn], M = 122;
void rsort() {
for (int i = 0; i <= M; ++i) tax[i] = 0;
for (int i = 1; i <= n; ++i) ++tax[rk[i]];
for (int i = 1; i <= M; ++i) tax[i] += tax[i - 1];
for (int i = n; i; --i) sa[tax[rk[tp[i]]]--] = tp[i];
}
int c1, H[maxn];
void SA() {
for (int i = 1; i <= n; ++i) rk[i] = s[i], tp[i] = i;
rsort();
for (int k = 1; k < n; k *= 2) {
if (c1 == n) break; M = c1; c1 = 0;
for (int i = n - k + 1; i <= n; ++i) tp[++c1] = i;
for (int i = 1; i <= n; ++i) if (sa[i] > k) tp[++c1] = sa[i] - k;
rsort(); swap(tp, rk); rk[sa[1]] = c1 = 1;
for (int i = 2; i <= n; ++i) {
if (tp[sa[i - 1]] != tp[sa[i]] || tp[sa[i - 1] + k] != tp[sa[i] + k]) ++c1;
rk[sa[i]] = c1;
}
}
int lcp = 0;
for (int i = 1; i <= n; ++i) {
if (lcp) --lcp;
int j = sa[rk[i] - 1];
while (s[j + lcp] == s[i + lcp]) ++lcp;
H[rk[i]] = lcp;
}
}
ll ans;
int main() {
scanf("%d%s", &n, s + 1); SA();
for (int i = 1; i <= n; ++i) ans += n - sa[i] + 1 - H[i];
cout << ans << endl;
return 0;
}
【后缀数组】【LuoguP2408】 不同子串个数的更多相关文章
- [spoj DISUBSTR]后缀数组统计不同子串个数
题目链接:https://vjudge.net/contest/70655#problem/C 后缀数组的又一神奇应用.不同子串的个数,实际上就是所有后缀的不同前缀的个数. 考虑所有的后缀按照rank ...
- SPOJ SUBST1 New Distinct Substrings(后缀数组 本质不同子串个数)题解
题意: 问给定串有多少本质不同的子串? 思路: 子串必是某一后缀的前缀,假如是某一后缀\(sa[k]\),那么会有\(n - sa[k] + 1\)个前缀,但是其中有\(height[k]\)个和上一 ...
- SPOJ Distinct Substrings(后缀数组求不同子串个数,好题)
DISUBSTR - Distinct Substrings no tags Given a string, we need to find the total number of its dist ...
- SPOJ(后缀数组求不同子串个数)
DISUBSTR - Distinct Substrings Given a string, we need to find the total number of its distinct subs ...
- [TyvjP1515] 子串统计 [luoguP2408] 不同子串个数(后缀数组)
Tyvj传送门 luogu传送门 经典题 统计一个字符串中不同子串的个数 一个字符串中的所有子串就是所有后缀的前缀 先求出后缀数组,求出后缀数组中相邻两后缀的 lcp 那么按照后缀数组中的顺序遍历求解 ...
- luoguP2408不同子串个数
传送门 可以知道每一个子串都是后缀的前缀,那么对于第\(i\)小的后缀的贡献就可以表示为n-sa[i]+1 然而会存在重复的子串,注意height数组的定义,对于sa[i-1]和sa[i],只有hei ...
- SPOJ REPEATS Repeats (后缀数组 + RMQ:子串的最大循环节)题解
题意: 给定一个串\(s\),\(s\)必有一个最大循环节的连续子串\(ss\),问最大循环次数是多少 思路: 我们可以知道,如果一个长度为\(L\)的子串连续出现了两次及以上,那么必然会存在\(s[ ...
- spoj705 后缀数组求不同子串的个数
http://www.spoj.com/problems/SUBST1/en/ 题目链接 SUBST1 - New Distinct Substrings no tags Given a stri ...
- spoj 694. Distinct Substrings 后缀数组求不同子串的个数
题目链接:http://www.spoj.com/problems/DISUBSTR/ 思路: 每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数.如果所有的后缀按照su ...
- 【Poj-3693】Maximum repetition substring 后缀数组 连续重复子串
POJ - 3693 题意 SPOJ - REPEATS的进阶版,在这题的基础上输出字典序最小的重复字串. 思路 跟上题一样,先求出最长的重复次数,在求的过程中顺便纪录最多次数可能的长度. 因为sa数 ...
随机推荐
- 据时间生成唯一序列ID
据时间生成唯一序列ID /** * <html> * <body> * <P> Copyright 1994 JsonInternational</p> ...
- ASP.NET SignalR 系列(五)之群组推送
在上一章介绍了 一对一推送的方式,这章重点介绍下群组推送和多人推送 群组主要就是用到了方法:Groups.Add(Context.ConnectionId, groupName); 将不同的连接id加 ...
- CephFS 使用
原文:https://www.jianshu.com/p/c22ff79c4452 之前介绍了 RBD 的使用方法,有了 RBD,远程磁盘挂载的问题就解决了,但 RBD 的问题是不能多个主机共享一个磁 ...
- Python进阶----进程之间通信(互斥锁,队列(参数:timeout和block),), ***生产消费者模型
Python进阶----进程之间通信(互斥锁,队列(参数:timeout和block),), ***生产消费者模型 一丶互斥锁 含义: 每个对象都对应于一个可称为" 互斥锁&qu ...
- 【面试突击】-Redis常见面试题(一)
介绍:Redis 是一个开源的使用 ANSI C 语言编写.遵守 BSD 协议.支持网络.可基于内存亦可持久化的日志型.Key-Value 数据库,并提供多种语言的 API的非关系型数据库. 传统数据 ...
- Flink原理、实战与性能优化读书笔记
第一章 ApacheFlink介绍 一.Flink优势 1. 目前唯一同时支持高吞吐.低延迟.高性能的分布式流式数据处理框架 2. 支持事件事件概念 3. 支持有状态计算,保持了事件原本产生的时序性, ...
- ABAP-System Functions
ABAP_CALLSTACK ABAP_CRC64 ABAP_PRECOMPILED_HEADER_USAGE ABSTOR_TEST AB_CALL_LITL_CHECK AB_CALL_STACK ...
- CentOS 7 - 以root身份登入Gnome
新版的7.0很多资料没有,为了安全,linux是禁止root登录到桌面,但为了方便又想用root登录到桌面,在网上找了找,基本上都是这这一篇: http://shaoguangleo.blog.163 ...
- Linux目录结构说明
文件系统层级标准(filesystem hierarchy standard,FHS). http://www.pathname.com/fhs/pub/fhs-2.3.html 以下是对这些目录的解 ...
- 如何自行给指定的SAP OData服务添加自定义日志记录功能
有的时候,SAP标准的OData实现或者相关的工具没有提供我们想记录的日志功能,此时可以利用SAP系统强大的扩展特性,进行自定义日志功能的二次开发. 以SAP CRM Fiori应用"My ...