后缀数组---New Distinct Substrings
Description
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
- 题意:给一个字符串长小于50000,求这个字符串的不同子串的个数;
- 思路:使用后缀数组算法先求出sa[],sa[i]表示排第i的后缀的开始位置下标,然后求出height[]数组,height[i]表示排名第i的后缀和排名第i-1的后缀的最大公共前缀的长度,容易知道排名i和i-1的串的子串重复个数为height[i]个,而原始串的子串个数为sum=n*(n+1)/2,故用sum减去所有的henght[]即为结果;
- #include <iostream>
- #include <algorithm>
- #include <cstdio>
- #include <cstring>
- #define rep(i,n) for(int i = 0;i < n; i++)
- using namespace std;
- const int size=,INF=<<;
- int rk[size],sa[size],height[size],w[size],wa[size],res[size];
- void getSa (int len,int up) {
- int *k = rk,*id = height,*r = res, *cnt = wa;
- rep(i,up) cnt[i] = ;
- rep(i,len) cnt[k[i] = w[i]]++;
- rep(i,up) cnt[i+] += cnt[i];
- for(int i = len - ; i >= ; i--) {
- sa[--cnt[k[i]]] = i;
- }
- int d = ,p = ;
- while(p < len){
- for(int i = len - d; i < len; i++) id[p++] = i;
- rep(i,len) if(sa[i] >= d) id[p++] = sa[i] - d;
- rep(i,len) r[i] = k[id[i]];
- rep(i,up) cnt[i] = ;
- rep(i,len) cnt[r[i]]++;
- rep(i,up) cnt[i+] += cnt[i];
- for(int i = len - ; i >= ; i--) {
- sa[--cnt[r[i]]] = id[i];
- }
- swap(k,r);
- p = ;
- k[sa[]] = p++;
- rep(i,len-) {
- if(sa[i]+d < len && sa[i+]+d <len &&r[sa[i]] == r[sa[i+]]&& r[sa[i]+d] == r[sa[i+]+d])
- k[sa[i+]] = p - ;
- else k[sa[i+]] = p++;
- }
- if(p >= len) return ;
- d *= ,up = p, p = ;
- }
- }
- void getHeight(int len) {
- rep(i,len) rk[sa[i]] = i;
- height[] = ;
- for(int i = ,p = ; i < len - ; i++) {
- int j = sa[rk[i]-];
- while(i+p < len&& j+p < len&& w[i+p] == w[j+p]) {
- p++;
- }
- height[rk[i]] = p;
- p = max(,p - );
- }
- }
- int getSuffix(char s[]) {
- int len = strlen(s),up = ;
- for(int i = ; i < len; i++) {
- w[i] = s[i];
- up = max(up,w[i]);
- }
- w[len++] = ;
- getSa(len,up+);
- getHeight(len);
- return len;
- }
- int main()
- {
- int T;
- long long sum;
- char s[size];
- scanf("%d",&T);
- while(T--)
- {
- scanf("%s",s);
- sum=;
- getSuffix(s);
- long long len=strlen(s);
- for(int i=;i<=len;i++)
- sum+=height[i];
- sum=len*(len+)/-sum;
- printf("%lld\n",sum);
- }
- }
后缀数组---New Distinct Substrings的更多相关文章
- SPOJ 694. Distinct Substrings (后缀数组不相同的子串的个数)转
694. Distinct Substrings Problem code: DISUBSTR Given a string, we need to find the total number o ...
- 后缀数组: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/New Distinct Substrings(后缀数组)
[SPOJ]Distinct Substrings/New Distinct Substrings(后缀数组) 题面 Vjudge1 Vjudge2 题解 要求的是串的不同的子串个数 两道一模一样的题 ...
- Distinct Substrings(spoj694)(sam(后缀自动机)||sa(后缀数组))
Given a string, we need to find the total number of its distinct substrings. Input \(T-\) number of ...
- 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 ...
- SPOJ Distinct Substrings(后缀数组求不同子串个数,好题)
DISUBSTR - Distinct Substrings no tags Given a string, we need to find the total number of its dist ...
- New Distinct Substrings(后缀数组)
New Distinct Substrings(后缀数组) 给定一个字符串,求不相同的子串的个数.\(n<=50005\). 显然,任何一个子串一定是后缀上的前缀.先(按套路)把后缀排好序,对于 ...
- spoj - Distinct Substrings(后缀数组)
Distinct Substrings 题意 求一个字符串有多少个不同的子串. 分析 又一次体现了后缀数组的强大. 因为对于任意子串,一定是这个字符串的某个后缀的前缀. 我们直接去遍历排好序后的后缀字 ...
- SPOJ705 Distinct Substrings (后缀自动机&后缀数组)
Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...
随机推荐
- [转]Sql Server 给表与字段添加描述
/* 在SQL语句中通过系统存储过sp_addextendedproperty可为表字段添加上动态的说明(备注)下面是SQL SERVER帮助文档中对sp_addextendedproperty存储过 ...
- mshadow笔记
矩阵维度表示和正常相反. a[2][3],行2列3,a.shape.shape_[0]=3,a.shape.shape_[1]=2. pred.Resize( Shape2( batch_size, ...
- [PaPaPa][需求说明书][V0.2]
PaPaPa软件需求说明书V0.2 前 言 经过第一版本的需求说明书之后,我发现博客园不让我把文章发到首页,那么对于这种情况该怎么办呢?我决定立马发布V0.2版本来挑战一下博客园的审核制度,嘿嘿 ...
- 一个自动备份mysql数据库的bat文件内容
自动备份mysql数据库,并已当前的日期时间为目录 copy过去, xcopy将近15年没有用dos命令,还是这么亲切 另 本方法是备份数据库文件,不是dump导出,然后再计划任务中使用,我用的是wa ...
- Application MyTest has not been registered. This is either due to a require() error during initialization or failure to call AppRegistry.registerComponent.
运行react-native项目时报错. 说明一下:项目本来是好的,再次运行就报错了 解决解决办法倒是有,不过具体什么原因不知道.希望有知道具体原因的童鞋能够补充一下 第一种情况:真的是注册的时候写错 ...
- 【Android】Kill Service
花了一天时间对如何Android保证Service不被杀死研究了一下,我的手机是Nexus5,系统4.4.2. 杀死一个Service通常有以下几种可能: 1)APP自己杀死(包括调用stopServ ...
- HTML5大数据可视化效果(二)可交互地铁线路图
前言 最近特别忙,承蒙大伙关照,3D机房的项目一个接着一个,领了一帮小弟,搞搞传帮带,乌飞兔走,转眼已经菊黄蟹肥……有个小弟很不错,勤奋好学,很快就把API都摸透了,自己折腾着做了个HTML5的魔都的 ...
- NoSql---MongoDB基本操作
MongoDB 最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语 言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引.最后由于 MongoDB 可以支 ...
- mysql中替换字符串(正则) 模糊
例如: abcd(efg)hijk 替换之后是abcdhijk , name)),''); 执行之后,报错:Truncated incorrect DOUBLE value解决办法,经过查询发现是co ...
- SNF开发平台WinForm之九-代码生成器使用说明-SNF快速开发平台3.3-Spring.Net.Framework
下面就具体的使用说明: 1.获取代码生成器的授权码(根据本机)-----还原数据库-------改config-----代码生成器 改代码生成器Config 2.登录代码生成器 3.查看是否连接成功 ...