SPOJ 694 Distinct Substrings/SPOJ 705 New Distinct Substrings(后缀数组)
Given a string, we need to find the total number of its distinct substrings.
Input
T- number of test cases. T<=20; Each test case consists of one string, whose length is <= 50000
Output
For each test case output one number saying the number of distinct substrings.
Example
Input:
2
CCCCC
ABABA Output:
5
9
题目大意:给一个字符串,问这个字符串中不同的子串一共有多少个。
思路:构建后缀数组。如样例ABABA的5个后缀排序后分别为:
A
ABA
ABABA
BA
BABA
我们可以看作所有后缀的所有前缀构成所有的子串。
从上面可以看出,在A中,A第一次出现。在ABA中,AB和ABA第一次出现。在ABABA中,ABAB和ABABA第一次出现。
那么容易看出,对于一个suffix(sa[i]),其中有height[i]个子串是和前一个重复了的。其他都没有和前一个重复,而且他们都不会和之前所有的子串重复(因为如果前面有和suffix(sa[i])的前缀子串重复的次数比suffix(sa[i-1])要多的话,它应该在suffix(sa[i])和suffix(sa[i-1])之间,这显然不符合后缀数组的性质)
所以求出height[]数组后,总的子串数为n*(n+1)/2,那么答案就为n*(n+1)/2 - sum{height[]}
代码(705:0.75S)
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long LL; const int MAXN = ; int sa[MAXN], c[MAXN], rank[MAXN], height[MAXN], tmp[MAXN];
char s[MAXN];
int T, n; void makesa(int m) {
memset(c, , m * sizeof(int));
for(int i = ; i < n; ++i) ++c[rank[i] = s[i]];
for(int i = ; i < m; ++i) c[i] += c[i - ];
for(int i = ; i < n; ++i) sa[--c[rank[i]]] = i;
for(int k = ; k < n; k <<= ) {
for(int i = ; i < n; ++i) {
int j = sa[i] - k;
if(j < ) j += n;
tmp[c[rank[j]]++] = j;
}
int j = c[] = sa[tmp[]] = ;
for(int i = ; i < n; ++i) {
if(rank[tmp[i]] != rank[tmp[i - ]] || rank[tmp[i] + k] != rank[tmp[i - ] + k])
c[++j] = i;
sa[tmp[i]] = j;
}
memcpy(rank, sa, n * sizeof(int));
memcpy(sa, tmp, n * sizeof(int));
}
} void calheight() {
for(int i = , k = ; i < n; height[rank[i++]] = k) {
if(k > ) --k;
int j = sa[rank[i] - ];
while(s[i + k] == s[j + k]) ++k;
}
} LL solve() {
LL ret = LL(n) * (n - ) / ;
for(int i = ; i < n; ++i) ret -= height[i];
return ret;
} int main() {
scanf("%d", &T);
while(T--) {
scanf("%s", s);
n = strlen(s) + ;
makesa();
calheight();
printf("%lld\n", solve());
}
}
SPOJ 694 Distinct Substrings/SPOJ 705 New Distinct Substrings(后缀数组)的更多相关文章
- SPOJ 694. Distinct Substrings (后缀数组不相同的子串的个数)转
694. Distinct Substrings Problem code: DISUBSTR Given a string, we need to find the total number o ...
- 705. New Distinct Substrings spoj(后缀数组求所有不同子串)
705. New Distinct Substrings Problem code: SUBST1 Given a string, we need to find the total number o ...
- SPOJ 694&&SPOJ705: Distinct Substrings
DISUBSTR - Distinct Substrings 链接 题意: 询问有多少不同的子串. 思路: 后缀数组或者SAM. 首先求出后缀数组,然后从对于一个后缀,它有n-sa[i]-1个前缀,其 ...
- SPOJ 705 Distinct Substrings(后缀数组)
[题目链接] http://www.spoj.com/problems/SUBST1/ [题目大意] 给出一个串,求出不相同的子串的个数. [题解] 对原串做一遍后缀数组,按照后缀的名次进行遍历, 每 ...
- 【SPOJ】Distinct Substrings/New Distinct Substrings(后缀数组)
[SPOJ]Distinct Substrings/New Distinct Substrings(后缀数组) 题面 Vjudge1 Vjudge2 题解 要求的是串的不同的子串个数 两道一模一样的题 ...
- 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~New Distinct Substrings SPOJ - SUBST1~(后缀数组求解子串个数)
Spoj-DISUBSTR - Distinct Substrings New Distinct Substrings SPOJ - SUBST1 我是根据kuangbin的后缀数组专题来的 这两题题 ...
- 后缀数组:SPOJ SUBST1 - New Distinct Substrings
Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...
- spoj - Distinct Substrings(后缀数组)
Distinct Substrings 题意 求一个字符串有多少个不同的子串. 分析 又一次体现了后缀数组的强大. 因为对于任意子串,一定是这个字符串的某个后缀的前缀. 我们直接去遍历排好序后的后缀字 ...
随机推荐
- iOS universallinks唤醒app
从iOS9之后,苹果就推出了这个功能,用来唤醒外部app.这个功能在那些电商app上使用尤其广泛,当你打开对应的h5网页后,上面跳出一个是否跳转app的按钮. 现在iOS11已经基本覆盖,iOS12也 ...
- 竞赛题解 - [CF 1080D]Olya and magical square
Olya and magical square - 竞赛题解 借鉴了一下神犇tly的博客QwQ(还是打一下广告) 终于弄懂了 Codeforces 传送门 『题目』(直接上翻译了) 给一个边长为 \( ...
- mysql 8.0.12 日常出错
最近不知道怎么回事,数据库老是会输出一个: [Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and co ...
- MySQL---正确使用索引、limit分页、执行计划、慢日志查询
正确使用索引 数据库表中添加索引后确实会让查询速度起飞,但前提必须是正确的使用索引来查询,如果以错误的方式使用,则即使建立索引也会不奏效.即使建立索引,索引也不会生效: - like '%xx' se ...
- 关于vue中mockjs的使用
使用vue的时候,后台可能不能及时作出接口,那么就需要我们前端自己模拟数据,使用mockjs可以进行模拟数据. 首先安装mockjs,cnpm install mockjs --save-dev: 其 ...
- 『Linux基础 - 1』计算机基础概念
这篇笔记的知识点结构目录: 认识计算机: (1)什么是计算机; (2)计算机的发展过程 计算机的构成: (1) 计算机硬件系统; (2) 计算机软件系统 二进制: (1) 为什么用二进制 (2) 二进 ...
- Old ST-LINK firmware detected.do you want to upgrade it?已解决,stlink升级
错误提示: 原因: stlink固件太旧了, 解决办法: 升级stlink固件,升级方法: 1. 下载st link utility工具. 官网下载:https://www.st.com/conten ...
- go包管理工具glide使用方法
golang没有官方最佳管理方案,在go的世界里存在大量的自制解决方案. go语言的包是没有中央库统一管理的,通过使用go get命令从远程代码库(github.com,goolge code 等)拉 ...
- vim 版本更新
sudo add-apt-repository ppa:jonathonf/vim sudo apt update sudo apt install vim 如果您想要卸载它, 请使用如下命令 sud ...
- Codeforces Round #482 (Div. 2) :B - Treasure Hunt
题目链接:http://codeforces.com/contest/979/problem/B 解题心得: 这个题题意就是三个人玩游戏,每个人都有一个相同长度的字符串,一共有n轮游戏,每一轮三个人必 ...