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 题意 求一个字符串有多少个不同的子串. 分析 又一次体现了后缀数组的强大. 因为对于任意子串,一定是这个字符串的某个后缀的前缀. 我们直接去遍历排好序后的后缀字 ...
随机推荐
- React--- react 初见React 总结
简介 react 程序代码是透明的,需要什么装什么 代码实现逻辑清晰可见 第一天 React 基础构造 分别是 继承的 React.component(继承的依赖类)/dom(dom元素)/pro ...
- 类似"音速启动"的原创工具简码"万能助手"在线用户数终于突破100了!
原本只是开发出来方便自己的一个小工具,看到群友也喜欢,就随手分享了, 经过1个多月的自然积累,在线用户数终于突破100了,这增长速度实在让人泪奔~ 博客园的朋友如果看到,喜欢的话就拿去用吧, 万能助手 ...
- #leetcode刷题之路12-整数转罗马数字
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值I 1V 5X 10L 50C 100D 500M 1000 例如, 罗马数字 2 写做 II ,即为两个并列的 1.12 ...
- php bug 调试助手 debug_print_backtrace()
debug_print_backtrace() 是一个很低调的函数,很少有人注意过它. 不过当我对着一个对象调用另一个对象再调用其它的对象和文件中的一个函数出错时,它也许正在一边笑呢 如果我们想知道某 ...
- 【Hive三】Hive理论
1. Hive基础 1. Hive基础 Hive基本概念 引入原因: Hive是什么 Hive数据管理 四种数据模型 Hive内部表和外部表 Hive数据类型 Hive的优化 Map的优化: Redu ...
- [SGU223]Little Kings(状压DP)
随便DP一下 Code #include <cstdio> int sta[150],cnt[150],tp,n,k; long long dp[12][144][150],Ans; in ...
- java中stream部分笔记
Stream流表面上看起来与集合类似,允许你转换和检索数据.然而,两者却有显著的不同1.流不存储元素.它们存储在底层的集合或者按需生成2.流操作不改变他们的源数据.例如filter方法不会从一个新流中 ...
- 北京Uber优步司机奖励政策(1月17日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 4245: [ONTAK2015]OR-XOR
4245: [ONTAK2015]OR-XOR https://www.lydsy.com/JudgeOnline/problem.php?id=4245 /* 要求分成m份,总价值为a1|a2|a3 ...
- Android UI控件:TextView
TextVIew的属性详解 android:autoLink设置是否当文本为URL链接/email/电话号码/map时,文本显示为可点击的链接.可选值(none/web /email/phone/ma ...