【spoj SUBST1】 New Distinct Substrings
http://www.spoj.com/problems/SUBST1/ (题目链接)
题意
求字符串的不相同的子串个数
Solution
后缀数组论文题。
每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数。如果所有的后缀按照 suffix(sa[1]), suffix(sa[2]), suffix(sa[3]), …… ,suffix(sa[n])的顺序计算,不难发现,对于每一次新加进来的后缀suffix(sa[k]),它将产生n-sa[k]+1个新的前缀。但是其中有height[k]个是和前面的字符串的前缀是相同的。所以suffix(sa[k])将“贡献” 出n-sa[k]+1- height[k]个不同的子串。累加后便是原问题的答案。这个做法的时间复杂度为 O(n)。
细节
开LL
代码
// spoj705
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#include<set>
#define LL long long
#define inf 1<<30
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; const int maxn=100010;
int sa[maxn],height[maxn],rank[maxn];
char s[maxn]; namespace Suffix {
int wa[maxn],wb[maxn],ww[maxn];
bool cmp(int *r,int a,int b,int l) {
return r[a]==r[b] && r[a+l]==r[b+l];
}
void da(char *r,int *sa,int n,int m) {
int i,j,p,*x=wa,*y=wb;
for (i=0;i<=m;i++) ww[i]=0;
for (i=1;i<=n;i++) ww[x[i]=r[i]]++;
for (i=1;i<=m;i++) ww[i]+=ww[i-1];
for (i=n;i>=1;i--) sa[ww[x[i]]--]=i;
for (p=0,j=1;p<n;j*=2,m=p) {
for (p=0,i=n-j+1;i<=n;i++) y[++p]=i;
for (i=1;i<=n;i++) if (sa[i]>j) y[++p]=sa[i]-j;
for (i=0;i<=m;i++) ww[i]=0;
for (i=1;i<=n;i++) ww[x[y[i]]]++;
for (i=1;i<=m;i++) ww[i]+=ww[i-1];
for (i=n;i>=1;i--) sa[ww[x[y[i]]]--]=y[i];
for (swap(x,y),p=x[sa[1]]=1,i=2;i<=n;i++) {
x[sa[i]]=cmp(y,sa[i-1],sa[i],j) ? p : ++p;
}
}
}
void calheight(char *r,int *sa,int n) {
for (int i=1;i<=n;i++) rank[sa[i]]=i;
for (int k=0,i=1;i<=n;i++) {
if (k) k--;
int j=sa[rank[i]-1];
while (r[i+k]==r[j+k]) k++;
height[rank[i]]=k;
}
}
}
int main() {
int T;scanf("%d",&T);
while (T--) {
scanf("%s",s+1);
int n=strlen(s+1);
Suffix::da(s,sa,n,300);
Suffix::calheight(s,sa,n);
LL ans=0;
for (int i=1;i<=n;i++) ans+=(n-sa[i]+1)-height[i];
printf("%lld\n",ans);
}
return 0;
}
【spoj SUBST1】 New Distinct Substrings的更多相关文章
- 【SPOJ – SUBST1】New Distinct Substrings 后缀数组
New Distinct Substrings 题意 给出T个字符串,问每个字符串有多少个不同的子串. 思路 字符串所有子串,可以看做由所有后缀的前缀组成. 按照后缀排序,遍历后缀,每次新增的前缀就是 ...
- SPOJ - SUBST1 D - New Distinct Substrings
D - New Distinct Substrings 题目大意:求一个字符串中不同子串的个数. 裸的后缀数组 #include<bits/stdc++.h> #define LL lon ...
- [SPOJ]DISUBSTR:Distinct Substrings&[SPOJ]SUBST1:New Distinct Substrings
题面 Vjudge Vjudge Sol 求一个串不同子串的个数 每个子串一定是某个后缀的前缀,也就是求所有后缀不同前缀的个数 每来一个后缀\(suf(i)\)就会有,\(len-sa[i]+1\)的 ...
- 【 SPOJ - GRASSPLA】 Grass Planting (树链剖分+树状数组)
54 种草约翰有 N 个牧场,编号为 1 到 N.它们之间有 N − 1 条道路,每条道路连接两个牧场.通过这些道路,所有牧场都是连通的.刚开始的时候,所有道路都是光秃秃的,没有青草.约翰会在一些道 ...
- SPOJ 题目705 New Distinct Substrings(后缀数组,求不同的子串个数)
SUBST1 - New Distinct Substrings no tags Given a string, we need to find the total number of its di ...
- 【Codeforces 258D】 Count Good Substrings
[题目链接] http://codeforces.com/contest/451/problem/D [算法] 合并后的字符串一定是形如"ababa","babab&qu ...
- 【SPOJ 694】Distinct Substrings (更直接的求法)
[链接]h在这里写链接 [题意] 接上一篇文章 [题解] 一个字符串所有不同的子串的个数=∑(len-sa[i]-height[i]) [错的次数] 0 [反思] 在这了写反思 [代码] #inclu ...
- 【SPOJ 694】Distinct Substrings
[链接]h在这里写链接 [题意] 给你一个长度最多为1000的字符串 让你求出一个数x,这个x=这个字符串的不同子串个数; [题解] 后缀数组题. 把原串复制一份,加在 ...
- 【SPOJ】694. Distinct Substrings
http://www.spoj.com/problems/DISUBSTR/ 题意:求字符串不同子串的数目. #include <bits/stdc++.h> using namespac ...
随机推荐
- 2019网易笔试题C++--丰收
题目描述 又到了丰收的季节,恰好小易去牛牛的果园里游玩. 牛牛常说他多整个果园的每个地方都了如指掌,小易不太相信,所以他想考考牛牛. 在果园里有N堆苹果,每堆苹果的数量为ai,小易希望知道从左往右数第 ...
- 使用AD对Linux客户端进行身份验证
https://technet.microsoft.com/zh-cn/library/2008.12.linux.aspx
- kubernetes集群部署mysql 8.0
参考:https://blog.csdn.net/sealir/article/details/81177747?utm_source=blogxgwz1 集群内安装mysql并添加相应存储(PVC) ...
- 为什么HashMap桶(链表)的长度超过8会转换成红黑树?
百度了一下,感觉能说清楚的并不多,所以在此记录一下. 首先说一说转换为红黑树的必要性: 红黑树的插入.删除和遍历的最坏时间复杂度都是log(n), 因此,意外的情况或者恶意使用下导致hashCode( ...
- XSS(Cross Site Script)
类型一:反射型XSS 简单地把用户输入的数据“反射”给浏览器.也就是说,黑客需要诱使用户“点击”一个恶意链接,才能攻击成功. 类型二:存储型XSS 把用户输入的数据“存储”在服务器端.这种XSS具有很 ...
- MFC常用操作
目录: 1.文件操作 1.1.获取文件大小 2.路径操作 2.1.创建多级目录 1.文件操作 1.1.获取文件大小 // 获取文件大小 ULONGLONG size = ; // 文件大小 CFile ...
- Python之并发编程-协程
目录 一.介绍 二. yield.greenlet.gevent介绍 1.yield 2.greenlet 3.gevent 一.介绍 协程:是单线程下的并发,又称微线程,纤程.英文名Coroutin ...
- 【Alpha】阶段第七次Scrum Meeting
[Alpha]阶段第七次Scrum Meeting 工作情况 团队成员 今日已完成任务 明日待完成任务 刘峻辰 增加上课信息接口 编写按学院搜索课程接口 赵智源 构建后测试点测试框架 构建前测试点测试 ...
- 20162328蔡文琛 week10 大二
20162328 2017-2018-1 <程序设计与数据结构>第十周学习总结 教材学习内容总结 理解图与有向图.无向图 理解带权图 会应用带权图 理解图的广度优先遍历和深度优先遍历 掌握 ...
- java 线程的简单理解
想要实现线程可以继承Thread也可以实现接口runnable,在类中重写 run()方法在主函数调用start方法就可以开辟线程. 对于java对象都有一个wait()和notify().notif ...