SPOJ 694
题意:
给一个字符串,求它有多少个不同的子串
多组数据。
Solution :
模板题,用所有的减去重复的即可。
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1e6;
char str[N + 1];
namespace SA {
int sa[N + 1], rk[N + 1], height[N + 1];
int a[N+1], set[N+1], n;
int fir[N+1], sec[N+1], buc[N+1], tp[N+1];
void sufSort() {
n = strlen(str + 1);
copy(str + 1, str + 1 + n, set + 1);
sort(set + 1, set + n + 1);
int *end = unique(set + 1, set + n + 1);
for (int i = 1; i <= n; ++ i)
a[i] = lower_bound(set + 1, end, str[i]) - set;
fill(buc, buc + 1 + n, 0);
for (int i = 1; i <= n; ++ i) buc[a[i]] ++;
for (int i = 1; i <= n; ++ i) buc[i] += buc[i - 1];
for (int i = 1 ;i <= n; ++ i) rk[i] = buc[a[i] - 1] + 1;
for (int t = 1; t <= n; t <<= 1) {
copy(rk + 1, rk + 1 + n, fir + 1);//那张图
for (int i = 1; i <= n; ++ i) sec[i] = i + t > n ? 0 : rk[i + t];
fill(buc, buc + 1 + n, 0);//基排桶清空
for (int i = 1; i <= n; ++ i) buc[sec[i]] ++;
for (int i = 1; i <= n; ++ i) buc[i] += buc[i - 1];//统计比sec[i]小的数有多少个
//tp[i]为第二关键字为第i大的二元组在排序前的位置
//n - --buc[sec[i]]为排名(第几大), 排序前的位置自然是i.
for (int i = 1; i <= n; ++ i) tp[n - --buc[sec[i]]] = i;
fill(buc, buc + 1 + n, 0);
for (int i = 1; i <= n; ++ i) buc[fir[i]] ++;
for (int i = 1; i <= n; ++ i) buc[i] += buc[i - 1];
//i为第二关键字为j大的二元组的位置,j递增,即保证sec[i]递增, 所以基排就是正确的。
for (int j = 1, i; j <= n; ++ j) i = tp[j], sa[buc[fir[i]]--] = i;
//手模,理解.
bool unique = 1;//若关键字相同,则排名也要相同,而基排使rk不同
for (int j = 1, i, last = 0; j <= n; ++ j) {
i = sa[j];
if (!last) rk[i] = 1;
else if (sec[i] == sec[last] && fir[i] == fir[last])
rk[i] = rk[last], unique = 0;
else
rk[i] = rk[last] + 1;
last = i;
}
if (unique) break;//如果所有rk都不同,就证明排好了.
}
}
void getHeight() {
for (int i = 1, k = 0; i <= n; ++ i) {
if (rk[i] == 1) k = 0;
else {
if (k > 0) k --;
int j = sa[rk[i] - 1];
while (j + k <= n && i + k <= n && str[i + k] == str[j + k]) k ++;
}
height[rk[i]] = k;
}
}
}using namespace SA;
int main() {
int T; scanf("%d", &T);
while (T --) {
scanf("%s", str + 1);
int n = strlen(str + 1);
sufSort();
getHeight();
int ans = n * (n + 1) / 2;
for (int i = 2; i <= n; ++ i) ans -= height[i];
printf("%d\n", ans);
}
}
SPOJ 694的更多相关文章
- SPOJ 694. Distinct Substrings (后缀数组不相同的子串的个数)转
694. Distinct Substrings Problem code: DISUBSTR Given a string, we need to find the total number o ...
- spoj 694 求一个字符串中不同子串的个数
SPOJ Problem Set (classical) 694. Distinct Substrings Problem code: DISUBSTR Given a string, we need ...
- spoj 694. Distinct Substrings 后缀数组求不同子串的个数
题目链接:http://www.spoj.com/problems/DISUBSTR/ 思路: 每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数.如果所有的后缀按照su ...
- spoj 694 705 不相同的子串的个数
http://www.spoj.com/problems/SUBST1/ SUBST1 - New Distinct Substrings #suffix-array-8 Given a string ...
- SPOJ 694 Distinct Substrings
Distinct Substrings Time Limit: 1000ms Memory Limit: 262144KB This problem will be judged on SPOJ. O ...
- 【SPOJ 694】Distinct Substrings 不相同的子串的个数
不会FQ啊,没法评测啊,先存一下代码QAQ 2016-06-16神犇Menci帮我测过AC了,谢谢神犇Menci QwQ #include<cstdio> #include<cstr ...
- 后缀数组 SPOJ 694 Distinct Substrings
题目链接 题意:给定一个字符串,求不相同的子串的个数 分析:我们能知道后缀之间相同的前缀的长度,如果所有的后缀按照 suffix(sa[0]), suffix(sa[1]), suffix(sa[2] ...
- SPOJ 694 (后缀数组) Distinct Substrings
将所有后缀按照字典序排序后,每新加进来一个后缀,它将产生n - sa[i]个前缀.这里和小罗论文里边有点不太一样. height[i]为和字典序前一个的LCP,所以还要减去,最终累计n - sa[i] ...
- spoj 694(后缀数组)
题意:求一个字符串的不重复子串的个数. 分析:对于下标为i的位置,能够产生的前缀子串个数为len-i(下标从0开始),对于与它字典序相邻的后缀产生的子串是重复的(就是他们的最长公共前缀),所以我们要减 ...
- Distinct Substrings - spoj 694(不重复子串个数)
题目大意:RT 分析:练手题目....后缀数组确实很强大.....多理解height数组, 切勿使用模版,后缀数组本身就有很多细节,多犯错更有利理解这个算法. 代码如下: ========== ...
随机推荐
- <body> 中的 JavaScript 函数
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- Element.getBoundingClientRect()
Element.getBoundingClientRect()方法会返回元素的大小和相对于视口的位置 语法: var domRect = element.getBoundingClientRect() ...
- JWT如何在Spring Cloud微服务系统中在服务相互调时传递
转载请标明出处: http://blog.csdn.net/forezp/article/details/78676036 本文出自方志朋的博客 在微服务系统中,为了保证微服务系统的安全,常常使用jw ...
- Configuration 中无法自动注入依赖于component的bean
出现问题时我这样使用依赖注入 @Configuration public class WebServiceConfig { @Autowired private IMessageWebService ...
- jzoj100029. 【NOIP2017提高A组模拟7.8】陪审团(贪心,排序)
Description 陪审团制度历来是司法研究中的一个热议话题,由于陪审团的成员组成会对案件最终的结果产生巨大的影响,诉讼双方往往围绕陪审团由哪些人组成这一议题激烈争夺. 小 W 提出了一个甲乙双方 ...
- PHP | Uploading and reading of files and database 【PHP | 文件的上传和读取与数据库】
这是我自己的一个作业,用的是很基础的代码. 有错误的地方欢迎批评和指正! 这里最容易出错的地方在读取数据后向数据库表中插入数据是的数据格式! 文件上传的页面 uploading.php <htm ...
- Spring Boot多环境配置
在项目开发阶段,开发环境和实际生产环境是不一样,比如使用的数据库/服务连接配置等.因此,配置多个开发环境profile还是必要的 多环境的配置(yml)方式 配置其实很简单,在resource目录下, ...
- python实现简单决策树(信息增益)——基于周志华的西瓜书数据
数据集如下: 色泽 根蒂 敲声 纹理 脐部 触感 好瓜 青绿 蜷缩 浊响 清晰 凹陷 硬滑 是 乌黑 蜷缩 沉闷 清晰 凹陷 硬滑 是 乌黑 蜷缩 浊响 清晰 凹陷 硬滑 是 青绿 蜷缩 沉闷 清晰 ...
- git stash应用
今天在看一个bug,之前一个分支的版本是正常的,在新的分支上上加了很多日志没找到原因,希望回溯到之前的版本,确定下从哪个提交引入的问题,但是还不想把现在的修改提交,也不希望在Git上看到当前修改的版本 ...
- 吐血分享:QQ群霸屏技术教程(接单篇)
在文章<QQ群霸屏技术教程(利润篇)>中,阿力推推提及到QQ群霸屏技术变现的方式,稍显粗略,这里详尽介绍下(老鸟漂过). 资本 资本之上,才谈得上接单,没技能,接个毛线. 1擅长点. 建议 ...