SPOJ694 -- DISUBSTR 后缀树组求不相同的子串的个数
DISUBSTR - 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 <= 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.
题意:求不同的子串的个数。
首先要知道,任意子串必是某一后缀的前缀。对于suffix[sa[i]], 它有len-sa[i]个前缀,,其中lcp[i]个子串与suffix[sa[i-1]]的前缀重复。。
每次只需要加上 len-sa[i]-lcp[i]就行了。。
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const double eps = 1e-;
const int maxn = 2e4+;
int sa[maxn], k, len, tmp[maxn], rank[maxn];
string s;
bool cmp(int i, int j)
{
if (rank[i] != rank[j])
return rank[i] < rank[j];
else
{
int x = (i+k <= len ? rank[i+k] : -);
int y = (j+k <= len ? rank[j+k] : -);
return x < y;
}
}
void build_sa()
{
for (int i = ; i <= len; i++)
{
sa[i] = i;
rank[i] = (i < len ? s[i] : -);
}
for (k = ; k <= len; k *= )
{
sort (sa,sa+len+,cmp);
tmp[sa[]] = ;
for (int i = ; i <= len; i++)
{
tmp[sa[i]] = tmp[sa[i-]] + (cmp(sa[i-],sa[i])? : );
}
for (int i = ; i <= len; i++)
rank[i] = tmp[i];
}
}
int lcp[maxn];
void get_lcp()
{
for (int i = ; i < len; i++)
rank[sa[i]] = i;
int h = ;
lcp[] = ;
for (int i = ; i < len; i++)
{
int j = sa[rank[i]-];
if (h > )
h--;
for (; h+i < len && h+j < len; h++)
if (s[i+h] != s[j+h])
break;
lcp[rank[i]] = h;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int T;
scanf ("%d", &T);
while (T--)
{
cin >> s;
len = s.size();
build_sa();
get_lcp();
int ans = ;
for (int i = ; i <= len; i++)
{
ans += len - sa[i] - lcp[i];
}
printf ("%d\n",ans);
}
return ;
}
SPOJ694 -- DISUBSTR 后缀树组求不相同的子串的个数的更多相关文章
- HDU4622:Reincarnation(后缀数组,求区间内不同子串的个数)
Problem Description Now you are back,and have a task to do: Given you a string s consist of lower-ca ...
- 【BZOJ-1396&2865】识别子串&字符串识别 后缀自动机/后缀树组 + 线段树
1396: 识别子串 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 312 Solved: 193[Submit][Status][Discuss] ...
- SPOJ694 DISUBSTR --- 后缀数组 / 后缀自动机
SPOJ694 DISUBSTR 题目描述: Given a string, we need to find the total number of its distinct substrings. ...
- poj 2774 Long Long Message,后缀数组,求最长公共子串 hdu1403
题意:给出两个字符串,求最长公共子串的长度. 题解:首先将两个字符串连在一起,并在中间加一个特殊字符(字串中不存在的)切割,然后两个串的最长公共字串就变成了全部后缀的最长公共前缀.这时就要用到heig ...
- POJ3581---Sequence 后缀树组
题意:n个数字组成的序列,第一个数字最大,,把序列分成3部分,每个部分分别翻转,输出翻转后字典序最小的序列.. 后缀数组变一下,,先求出 第一个分割的位置,,然后再求一次后缀数组,,求出第二个位置.. ...
- CF504E Misha and LCP on Tree(树链剖分+后缀树组)
1A真舒服. 喜闻乐见的树链剖分+SA. 一个初步的想法就是用树链剖分,把两个字符串求出然后hash+二分求lcp...不存在的. 因为考虑到这个字符串是有序的,我们需要把每一条重链对应的字符串和这个 ...
- FZU 2137 奇异字符串 后缀树组+RMQ
题目连接:http://acm.fzu.edu.cn/problem.php?pid=2137 题解: 枚举x位置,向左右延伸计算答案 如何计算答案:对字符串建立SA,那么对于想双延伸的长度L,假如有 ...
- HDU4436---str2int 后缀树组(12年天津区域赛)
str2int Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total S ...
- 【文文殿下】后缀自动机(SAM)求最长公共子串的方法
首先,在A 串上建立一个SAM,然后用B串在上面跑.具体跑的方法是: 从根节点开始,建立一个指针 p ,指着B串的开头,同步移动指针,沿着SAM的边移动,如果可以移动(即存在边)那么万事皆好,直接le ...
随机推荐
- MySQL高可用基础之keepalived+双主复制【转】
环境:MySQL-VIP:192.168.1.3MySQL-master1:192.168.1.1MySQL-master2:192.168.1.2 OS版本:CentOS release 6.4 ( ...
- myqltransactionRollbackexception deadlock found when trying to get lock
linux 下远程连接mysq 命令: mysql -h "1.0.0.1" -u username -p 1 获 取锁等待情况 可以通过检查 table_locks_waited ...
- 再探Java基础——String.format(String format, Object… args)的使用
最近看到类似这样的一些代码:String.format("参数%s不能为空", "birthday"); 以前还没用过这功能不知咐意思,后研究了一下,详细讲解如 ...
- View原理
View处理: 绘制(paint canvas path:tween等动画效果).事件处理 参考整理自: Custom Components: http://developer.android.c ...
- 简单水池&&迷宫问题
#include <iostream> #include <stdio.h> #include <cstring> using namespace std; int ...
- Java Criteria表关联查询(两个表未定义关联关系)
Criteria criteria = this.getSession().createCriteria(Competition.class, "b"); DetachedCrit ...
- canvas toDataUrl 跨域问题
使用canvas 的 toDataUrl方法会遇到跨域问题 chrome 会报下面的错误: Uncaught SecurityError: Failed to execute 'toDataURL' ...
- mysql怎么限制某些查询语句的执行?
mysql怎么限制某些查询语句的执行? 比如某些sql语句执行时间很长,超过10s,怎么样超过10s就不让其执行? 后续更新中...
- ReportViewer2010冻结行列
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="NewTrackingVer ...
- MD5加密类
public class MD5Util { public static String getMD5(String s) { char hexDigits[] = {'0', '1', '2', '3 ...