Distinct Substrings

Time Limit: 1000ms
Memory Limit: 262144KB

This problem will be judged on SPOJ. Original ID: DISUBSTR
64-bit integer IO format: %lld      Java class name: Main

 

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 <= 1000

Output

For each test case output one number saying the number of distinct substrings.

Example

Sample Input:
2
CCCCC
ABABA

Sample Output:
5
9

Explanation for the testcase with string ABABA: 
len=1 : A,B
len=2 : AB,BA
len=3 : ABA,BAB
len=4 : ABAB,BABA
len=5 : ABABA
Thus, total number of distinct substrings is 9.

解题:求不同子串的个数,n - sa[i] - 1表示当前后缀的前缀个数,然后减去 height[i],也就是减去与前面的重复的。

 #include <bits/stdc++.h>
using namespace std;
const int maxn = ;
int sa[maxn],rk[maxn],height[maxn];
int c[maxn],t[maxn],t2[maxn],n;
char s[maxn];
void build_sa(int m) {
int i,j,*x = t,*y = t2;
for(i = ; i < m; ++i) c[i] = ;
for(i = ; i < n; ++i) c[x[i] = s[i]]++;
for(i = ; i < m; ++i) c[i] += c[i-];
for(i = n-; i >= ; --i) sa[--c[x[i]]] = i; for(int k = ; k <= n; k <<= ) {
int p = ;
for(i = n-k; i < n; ++i) y[p++] = i;
for(i = ; i < n; ++i)
if(sa[i] >= k) y[p++] = sa[i] - k;
for(i = ; i < m; ++i) c[i] = ;
for(i = ; i < n; ++i) c[x[y[i]]]++;
for(i = ; i < m; ++i) c[i] += c[i-];
for(i = n-; i >= ; --i)
sa[--c[x[y[i]]]] = y[i];
swap(x,y);
x[sa[]] = ;
p = ;
for(i = ; i < n; ++i)
if(y[sa[i]] == y[sa[i-]] && y[sa[i]+k] == y[sa[i-]+k])
x[sa[i]] = p-;
else x[sa[i]] = p++;
if(p >= n) break;
m = p;
}
}
void getHeight(){
int i,j,k = ;
for(i = ; i < n; ++i) rk[sa[i]] = i;
for(i = ; i < n; ++i){
if(k) --k;
j = sa[rk[i]-];
while(i+k<n&&j+k<n&&s[i+k]==s[j+k]) ++k;
height[rk[i]] = k;
}
}
int main() {
int kase;
scanf("%d",&kase);
while(kase--){
scanf("%s",s);
n = strlen(s) + ;
build_sa();
getHeight();
int ret = ;
for(int i = ; i < n; ++i)
ret += n - sa[i] - height[i] - ;
printf("%d\n",ret);
}
return ;
}

后缀自动机

 #include <bits/stdc++.h>
using namespace std;
const int maxn = ;
char str[maxn];
int ret,n;
struct SAM{
struct node{
int son[],f,len;
void init(){
f = -;
len = ;
memset(son,-,sizeof son);
}
}e[maxn];
int tot,last;
int newnode(int len = ){
e[tot].init();
e[tot].len = len;
return tot++;
}
void init(){
tot = last = ;
newnode();
}
void extend(int c){
int p = last,np = newnode(e[p].len + );
while(p != - && e[p].son[c] == -){
e[p].son[c] = np;
p = e[p].f;
}
if(p == -) e[np].f = ;
else{
int q = e[p].son[c];
if(e[p].len + == e[q].len) e[np].f = q;
else{
int nq = newnode();
e[nq] = e[q];
e[nq].len = e[p].len + ;
e[q].f = e[np].f = nq;
while(p != - && e[p].son[c] == q){
e[p].son[c] = nq;
p = e[p].f;
}
}
}
last = np;
}
void solve(){
ret = ;
for(int i = ; i < tot; ++i)
ret += e[i].len - e[e[i].f].len;
printf("%d\n",ret);
}
}sam; int main(){
int kase;
scanf("%d",&kase);
while(kase--){
scanf("%s",str);
n = strlen(str);
sam.init();
for(int i = ret = ; str[i]; ++i)
sam.extend(str[i]-'A');
sam.solve();
}
return ;
}

SPOJ 694 Distinct Substrings的更多相关文章

  1. SPOJ 694. Distinct Substrings (后缀数组不相同的子串的个数)转

    694. Distinct Substrings Problem code: DISUBSTR   Given a string, we need to find the total number o ...

  2. 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 ...

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

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

  4. 后缀数组 SPOJ 694 Distinct Substrings

    题目链接 题意:给定一个字符串,求不相同的子串的个数 分析:我们能知道后缀之间相同的前缀的长度,如果所有的后缀按照 suffix(sa[0]), suffix(sa[1]), suffix(sa[2] ...

  5. SPOJ 694 Distinct Substrings(不相同子串个数)

    https://vjudge.net/problem/SPOJ-DISUBSTR 题意: 给定一个字符串,求不相同的子串的个数. 思路: #include<iostream> #inclu ...

  6. 【SPOJ】Distinct Substrings(后缀自动机)

    [SPOJ]Distinct Substrings(后缀自动机) 题面 Vjudge 题意:求一个串的不同子串的数量 题解 对于这个串构建后缀自动机之后 我们知道每个串出现的次数就是\(right/e ...

  7. 【SPOJ】Distinct Substrings/New Distinct Substrings(后缀数组)

    [SPOJ]Distinct Substrings/New Distinct Substrings(后缀数组) 题面 Vjudge1 Vjudge2 题解 要求的是串的不同的子串个数 两道一模一样的题 ...

  8. 【SPOJ】Distinct Substrings

    [SPOJ]Distinct Substrings 求不同子串数量 统计每个点有效的字符串数量(第一次出现的) \(\sum\limits_{now=1}^{nod}now.longest-paren ...

  9. SPOJ - DISUBSTR Distinct Substrings (后缀数组)

    Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...

随机推荐

  1. .NET 拼音汉字转化(全面)

    引言 这是一个.NET 用C#语言编写的  拼音转汉字类,考虑到有很多拼音转汉字,但是试用过发现大部分有很多生僻字都没有办法显示.在此分享一个支持绝大多数的较为全面的拼音汉字转化帮助类.不多说,代码附 ...

  2. CodeForces 445E DZY Loves Colors

    DZY Loves Colors Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForces ...

  3. 洛谷 P2747 [USACO5.4]周游加拿大Canada Tour

    P2747 [USACO5.4]周游加拿大Canada Tour 题目描述 你赢得了一场航空公司举办的比赛,奖品是一张加拿大环游机票.旅行在这家航空公司开放的最西边的城市开始,然后一直自西向东旅行,直 ...

  4. TCO14 1B L3: EagleInZoo, dp,tree

    题目:http://community.topcoder.com/stat?c=problem_statement&pm=13117&rd=15950 看到树,又是与节点有关,通常是d ...

  5. 使用client对象模型读取SharePoint列表数据

    使用client对象模型读取SharePoint列表数据 client对象模型提供了强有力的方式.从远程client应用程序管理列表. 1. 管理员身份打开VS,新建项目Windows窗口应用程序,命 ...

  6. bzoj1211: [HNOI2004]树的计数(prufer序列+组合数学)

    1211: [HNOI2004]树的计数 题目:传送门 题解: 今天刚学prufer序列,先打几道简单题 首先我们知道prufer序列和一颗无根树是一一对应的,那么对于任意一个节点,假设这个节点的度数 ...

  7. [JSOI2008] [BZOJ1567] Blue Mary的战役地图 解题报告 (hash)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1567 Description Blue Mary最近迷上了玩Starcraft(星际争霸 ...

  8. Objects are mutable

    We can change the state of an object by making an assignment to one of its attributes. For example, ...

  9. 21.hash_map(已被废弃不再使用 被unordered_map代替)

    #include <string> //老版本的unordered_map(已经废弃不再使用) #include <hash_map> #include <iostrea ...

  10. animation和transition做动画的区别

    animation做动画,是不需要去触发的,可以定义一开始就执行 transition做动画,是需要人为触发,才能执行的