题目链接

题目描述

给你一个长为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】 不同子串个数的更多相关文章

  1. [spoj DISUBSTR]后缀数组统计不同子串个数

    题目链接:https://vjudge.net/contest/70655#problem/C 后缀数组的又一神奇应用.不同子串的个数,实际上就是所有后缀的不同前缀的个数. 考虑所有的后缀按照rank ...

  2. SPOJ SUBST1 New Distinct Substrings(后缀数组 本质不同子串个数)题解

    题意: 问给定串有多少本质不同的子串? 思路: 子串必是某一后缀的前缀,假如是某一后缀\(sa[k]\),那么会有\(n - sa[k] + 1\)个前缀,但是其中有\(height[k]\)个和上一 ...

  3. SPOJ Distinct Substrings(后缀数组求不同子串个数,好题)

    DISUBSTR - Distinct Substrings no tags  Given a string, we need to find the total number of its dist ...

  4. SPOJ(后缀数组求不同子串个数)

    DISUBSTR - Distinct Substrings Given a string, we need to find the total number of its distinct subs ...

  5. [TyvjP1515] 子串统计 [luoguP2408] 不同子串个数(后缀数组)

    Tyvj传送门 luogu传送门 经典题 统计一个字符串中不同子串的个数 一个字符串中的所有子串就是所有后缀的前缀 先求出后缀数组,求出后缀数组中相邻两后缀的 lcp 那么按照后缀数组中的顺序遍历求解 ...

  6. luoguP2408不同子串个数

    传送门 可以知道每一个子串都是后缀的前缀,那么对于第\(i\)小的后缀的贡献就可以表示为n-sa[i]+1 然而会存在重复的子串,注意height数组的定义,对于sa[i-1]和sa[i],只有hei ...

  7. SPOJ REPEATS Repeats (后缀数组 + RMQ:子串的最大循环节)题解

    题意: 给定一个串\(s\),\(s\)必有一个最大循环节的连续子串\(ss\),问最大循环次数是多少 思路: 我们可以知道,如果一个长度为\(L\)的子串连续出现了两次及以上,那么必然会存在\(s[ ...

  8. spoj705 后缀数组求不同子串的个数

    http://www.spoj.com/problems/SUBST1/en/  题目链接 SUBST1 - New Distinct Substrings no tags  Given a stri ...

  9. spoj 694. Distinct Substrings 后缀数组求不同子串的个数

    题目链接:http://www.spoj.com/problems/DISUBSTR/ 思路: 每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数.如果所有的后缀按照su ...

  10. 【Poj-3693】Maximum repetition substring 后缀数组 连续重复子串

    POJ - 3693 题意 SPOJ - REPEATS的进阶版,在这题的基础上输出字典序最小的重复字串. 思路 跟上题一样,先求出最长的重复次数,在求的过程中顺便纪录最多次数可能的长度. 因为sa数 ...

随机推荐

  1. ELK学习笔记之使用curl命令操作elasticsearch

    0x00 _cat系列 _cat系列提供了一系列查询elasticsearch集群状态的接口.你可以通过执行curl -XGET localhost:9200/_cat 1. 获取所有_cat系列的操 ...

  2. pandas-04 多级index操作

    pandas-04 多级index操作 在pandas中可以为series和dataframe设置多个index,也就是说可以有多级index和column.这样可以对pandas的操作更加灵活. i ...

  3. Tomcat启动找不到项目依赖jar的解决方式

    一.背景 最近在写一个MQ框架-gmq,先写的服务端,然后写客户端.感觉服务端和客户端分成两个独立的项目不合适,于是改成了maven父子模块的形式.父项目相当于一个壳,里面包含服务端.客户端两个模块. ...

  4. vue侦听器 基础4

    侦听器 使用方式:设置需要侦听的data里的属性名就可以了 new Vue({ el:"#app", data:{ count:0 }, watchers:{ count(){ / ...

  5. LocalStorageUtils

    对localStorage进行封装: var LocalStorageUtils = new function (){ if(window.localStorage==null){ throw new ...

  6. Java 之 设计模式——代理模式

    设计模式——代理模式 一.概述 1.代理模式 (1)真实对象:被代理的对象 (2)代理对象:代理真实对象的 (3)代理模式:代理对象代理真实对象,达到增强真实对象功能的目的 二.实现方式 1.静态代理 ...

  7. Appscan漏洞之会话标识未更新

    本次针对 Appscan漏洞 会话标识未更新 进行总结,如下: 1. 会话标识未更新 1.1.攻击原理 在认证用户或者以其他方式建立新用户会话时,如果不使任何现有会话标识失效,攻击者就有机会窃取已认证 ...

  8. nodejs SSL Error: CERT_UNTRUSTED while using npm command 错误

    SSH 使用错误,其实我们关掉HTTPS就好了 npm config set strict-ssl false 或者 npm config set registry="http://regi ...

  9. 【数据泵】EXPDP导出表结构

    [数据泵]EXPDP导出表结构(真实案例) BLOG文档结构图         因工作需要现需要把一个生产库下的元数据(表定义,索引定义,函数定义,包定义,存储过程)导出到测试库上,本来以为很简单的, ...

  10. Upgrade Windows Server 2016 to Windows Server 2019

    Pre-Upgrade Upgrade path: Windows Server 2016 can be upgraded to Windows 2019 in a single upgrade pr ...