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.

题意:

为字符串的子串个数

思路:

使用后缀数组解决。

按sa遍历后缀数组,每一个后缀的贡献即为n-sa[i]-lcp[i];

这里的lcp就是你们所说的height

#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime> #define fuck(x) cout<<#x<<" = "<<x<<endl;
#define debug(a, x) cout<<#a<<"["<<x<<"] = "<<a[x]<<endl;
#define ls (t<<1)
#define rs ((t<<1)|1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = ;
const int maxm = ;
const int inf = 0x3f3f3f3f;
const ll Inf = ;
const int mod = ;
const double eps = 1e-;
const double pi = acos(-); char s[maxn];
int len,Rank[maxn],sa[maxn],k,tmp[maxn];
bool compare_sa(int i, int j) {
if (Rank[i] != Rank[j]) { return Rank[i] < Rank[j]; }
//如果以i开始,长度为k的字符串的长度,已经超出了字符串尾,那么就赋值为-1
//这是因为,在前面所有数据相同的情况下,字符串短的字典序小.
int ri = i + k <= len ? Rank[i + k] : -inf;
int rj = j + k <= len ? Rank[j + k] : -inf;
return ri < rj;
} void construct_sa() {
//初始的RANK为字符的ASCII码
for (int i = ; i <= len; i++) {
sa[i] = i;
Rank[i] = i < len ? s[i] : -inf;
}
for (k = ; k <= len; k *= ) {
sort(sa, sa + len + , compare_sa);
tmp[sa[]] = ;
//全新版本的RANK,tmp用来计算新的rank
//将字典序最小的后缀rank计为0
//sa之中表示的后缀都是有序的,所以将下一个后缀与前一个后缀比较,如果大于前一个后缀,rank就比前一个加一.
//否则就和前一个相等.
for (int i = ; i <= len; i++) {
tmp[sa[i]] = tmp[sa[i - ]] + (compare_sa(sa[i - ], sa[i]) ? : );
}
for (int i = ; i <= len; i++) {
Rank[i] = tmp[i]; }
}
}
int lcp[maxn]; void construct_lcp(){
// for(int i=0;i<=n;i++){Rank[sa[i]]=i;} int h=;
lcp[]=;
for(int i=;i<len;i++){//i为后缀数组起始位置
int j = sa[Rank[i]-];//获取当前后缀的前一个后缀(排序后)
if(h>)h--;
for(;j+h<len&&i+h<len;h++){
if(s[j+h]!=s[i+h])break;
}
lcp[Rank[i]]=h;
}
} int main() {
int T;
scanf("%d",&T);
while (T--){
scanf("%s",s);
len = strlen(s);
construct_sa();
construct_lcp(); int ans=;
for(int i=;i<=len;i++){
ans+=(len-sa[i]-lcp[i]);
}
printf("%d\n",ans);
} return ;
}

SPOJ - DISUBSTR Distinct Substrings (后缀数组)的更多相关文章

  1. SPOJ DISUBSTR Distinct Substrings 后缀数组

    题意:统计母串中包含多少不同的子串 然后这是09年论文<后缀数组——处理字符串的有力工具>中有介绍 公式如下: 原理就是加上新的,减去重的,这题是因为打多校才补的,只能说我是个垃圾 #in ...

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

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

  3. SPOJ - SUBST1 New Distinct Substrings —— 后缀数组 单个字符串的子串个数

    题目链接:https://vjudge.net/problem/SPOJ-SUBST1 SUBST1 - New Distinct Substrings #suffix-array-8 Given a ...

  4. 【SPOJ – SUBST1】New Distinct Substrings 后缀数组

    New Distinct Substrings 题意 给出T个字符串,问每个字符串有多少个不同的子串. 思路 字符串所有子串,可以看做由所有后缀的前缀组成. 按照后缀排序,遍历后缀,每次新增的前缀就是 ...

  5. SPOJ 694 || 705 Distinct Substrings ( 后缀数组 && 不同子串的个数 )

    题意 : 对于给出的串,输出其不同长度的子串的种类数 分析 : 有一个事实就是每一个子串必定是某一个后缀的前缀,换句话说就是每一个后缀的的每一个前缀都代表着一个子串,那么如何在这么多子串or后缀的前缀 ...

  6. spoj Distinct Substrings 后缀数组

    给定一个字符串,求不相同的子串的个数. 假如给字符串“ABA";排列的子串可能: A B A AB  BA ABA 共3*(3+1)/2=6种; 后缀数组表示时: A ABA BA 对于A和 ...

  7. ●SPOJ 8222 NSUBSTR - Substrings(后缀数组)

    题链: http://www.spoj.com/problems/NSUBSTR/ 题解: 同届红太阳 --WSY给出的后缀数组解法!!! 首先用倍增算法求出 sa[i],rak[i],hei[i]然 ...

  8. [spoj694&spoj705]New Distinct Substrings(后缀数组)

    题意:求字符串中不同子串的个数. 解题关键:每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数. 1.总数减去height数组的和即可. 注意这里height中为什么不需 ...

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

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

随机推荐

  1. Person Re-identification 系列论文笔记(六):AlignedReID

    AlignedReID Zhang X, Luo H, Fan X, et al. AlignedReID: Surpassing Human-Level Performance in Person ...

  2. Leetcode728.Self Dividing Numbers自除数

    自除数 是指可以被它包含的每一位数除尽的数. 例如,128 是一个自除数,因为 128 % 1 == 0,128 % 2 == 0,128 % 8 == 0. 还有,自除数不允许包含 0 . 给定上边 ...

  3. 【风马一族_php】NO2_php基础知识

    原文来自:http://www.cnblogs.com/sows/p/5995763.html (博客园的)风马一族 侵犯版本,后果自负 回顾 什么是php以及php的发展史 搭建web服务器 apa ...

  4. keystone同步数据库的时候提示error

    keystone 在同步的时候报出以下错误: su -s /bin/sh -c "keystone-manage db_sync" keystone CRITICAL keysto ...

  5. MySQL中使用LIMIT进行分页的方法

    一.分页需求: 客户端通过传递start(页码),pageSize(每页显示的条数)两个参数去分页查询数据库表中的数据,那我们知道MySql数据库提供了分页的函数limit m,n,但是该函数的用法和 ...

  6. Effective C++: 05实现

    26:尽可能延后变量定义式的出现时间 1:只要你定义了一个变量而其类型带有一个构造函数或析构函数,那么当程序的控制流到达这个变量定义式时,你便得承受构造成本:当这个变量离开其作用域时,你便得承受析构成 ...

  7. 分享 KubeCon 2019 (上海)关于 Serverless 及 Knative 相关演讲会议

    有幸参加了 KubeCon 2019 上海大会,并参加了 Knative 及 Serverless 相关的几场分享会,收获满满.这里简单介绍一下各个演讲主题的主要内容.详细的演讲主题文档可以在Kube ...

  8. 从零学React Native之10Text

    在React Native开发中,所有需要显示的字符串文本都需要放置在Text或者Text的子组件中.虽然在之前的文章中多次使用了Text组件,但是Text组件还是值得专门学习的, 并没有想象中的那么 ...

  9. Android 高仿微信语音聊天页面高斯模糊效果

    目前的应用市场上,使用毛玻璃效果的APP随处可见,比如用过微信语音聊天的人可以发现,语音聊天页面就使用了高斯模糊效果. 先看下效果图: 仔细观察上图,我们可以发现,背景图以用户头像为模板,对其进行了高 ...

  10. hihocoder 1586 ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛-题目9 : Minimum【线段树】

    https://hihocoder.com/problemset/problem/1586 线段树操作,原来题并不难..... 当时忽略了一个重要问题,就是ax*ay要最小时,x.y可以相等,那就简单 ...