spoj 694 705 不相同的子串的个数
http://www.spoj.com/problems/SUBST1/
SUBST1 - New 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 <= 50000
Output
For each test case output one number saying the number of distinct substrings.
Example
Input:
2
CCCCC
ABABA Output:
5
9
代码:
//论文题,每个子串都是某个后缀的前缀,因此每个后缀的贡献是len-sa[i],去掉重复的就是len-sa[i]-he[i];
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=;
int he[MAXN+],ra[MAXN+],sa[MAXN+],xx[MAXN+],yy[MAXN+],buc[MAXN+];
char s[MAXN+];
int len,m;
void get_suf()
{
int *x=xx,*y=yy;
for(int i=;i<m;i++) buc[i]=;
for(int i=;i<len;i++) buc[x[i]=s[i]]++;
for(int i=;i<m;i++) buc[i]+=buc[i-];
for(int i=len-;i>=;i--) sa[--buc[x[i]]]=i;
for(int k=;k<=len;k<<=){
int p=;
for(int i=len-;i>=len-k;i--) y[p++]=i;
for(int i=;i<len;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
for(int i=;i<m;i++) buc[i]=;
for(int i=;i<len;i++) buc[x[y[i]]]++;
for(int i=;i<m;i++) buc[i]+=buc[i-];
for(int i=len-;i>=;i--) sa[--buc[x[y[i]]]]=y[i];
swap(x,y);
p=;x[sa[]]=;
for(int i=;i<len;i++){
if(y[sa[i-]]==y[sa[i]]&&y[sa[i-]+k]==y[sa[i]+k])
x[sa[i]]=p-;
else x[sa[i]]=p++;
}
if(p>=len) break;
m=p;
}
for(int i=;i<len;i++) ra[sa[i]]=i;
int k=;
for(int i=;i<len;i++){
if(ra[i]==) { he[]=;continue; }
if(k) k--;
int j=sa[ra[i]-];
while(s[i+k]==s[j+k]&&i+k<len&&j+k<len) k++;
he[ra[i]]=k;
}
}
int solve()
{
int ans=len-sa[];
for(int i=;i<len;i++){
ans+=(len-sa[i]-he[i]);
}
printf("%d\n",ans);
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%s",s);
len=strlen(s);
m=;
get_suf();
solve();
}
return ;
}
spoj 694 705 不相同的子串的个数的更多相关文章
- SPOJ 694 || 705 Distinct Substrings ( 后缀数组 && 不同子串的个数 )
题意 : 对于给出的串,输出其不同长度的子串的种类数 分析 : 有一个事实就是每一个子串必定是某一个后缀的前缀,换句话说就是每一个后缀的的每一个前缀都代表着一个子串,那么如何在这么多子串or后缀的前缀 ...
- 洛谷2408不同字串个数/SPOJ 694/705 (后缀数组SA)
真是一个三倍经验好题啊. 我们来观察这个题目,首先如果直接整体计算,怕是不太好计算. 首先,我们可以将每个子串都看成一个后缀的的前缀.那我们就可以考虑一个一个后缀来计算了. 为了方便起见,我们选择按照 ...
- SPOJ 694/705 后缀数组
思路: 论文题*n Σn-i-ht[i]+1 就是结果 O(n)搞定~ //By SiriusRen #include <cstdio> #include <cstring> ...
- SPOJ 694 && SPOJ 705 (不重复子串个数:后缀数组)
题意 给定一个字符串,求它的所有不重复子串的个数 思路 一个字符串的子串都必然是它的某个后缀的前缀.对于每一个sa[i]后缀,它的起始位置sa[i],那么它最多能得到该后缀长度个子串(n-sa[i]个 ...
- SPOJ 694. Distinct Substrings (后缀数组不相同的子串的个数)转
694. Distinct Substrings Problem code: DISUBSTR Given a string, we need to find the total number o ...
- SPOJ 694 Distinct Substrings(不相同子串个数)
https://vjudge.net/problem/SPOJ-DISUBSTR 题意: 给定一个字符串,求不相同的子串的个数. 思路: #include<iostream> #inclu ...
- SPOJ - DISUBSTR 多少个不同的子串
694. Distinct Substrings Problem code: DISUBSTR Given a string, we need to find the total number o ...
- SPOJ 694 Distinct Substrings
Distinct Substrings Time Limit: 1000ms Memory Limit: 262144KB This problem will be judged on SPOJ. O ...
- 后缀数组 SPOJ 694 Distinct Substrings
题目链接 题意:给定一个字符串,求不相同的子串的个数 分析:我们能知道后缀之间相同的前缀的长度,如果所有的后缀按照 suffix(sa[0]), suffix(sa[1]), suffix(sa[2] ...
随机推荐
- Centos7与Centos6的区别
CentOS7 修改网卡名称为eth0.eth1 方法1 修改网卡名称 cd /etc/sysconfig/network-scripts/ mv ifcfg-eno16777736 ifcfg-et ...
- python format用法详解
#常用方法:print('{0},{1}'.format('zhangk', 32)) print('{},{},{}'.format('zhangk','boy',32)) print('{name ...
- 404 Note Found 现场编程
目录 组员职责分工 github 的提交日志截图 程序运行截图 程序运行环境 GUI界面 基础功能实现 运行视频 LCG算法 过滤(降权)算法 算法思路 红黑树 附加功能一 背景 实现 附加功能二(迭 ...
- virsh 命令行管理虚拟机
重用命令和选项 1:查看运行的虚拟机 virsh list 2:查看所有的虚拟机(关闭和运行的虚拟机) virsh list --all 3:连接虚拟机 virsh console +域名(虚 ...
- 明白JavaScript原型链和JavaScrip继承
原型链是JavaScript的基础性内容之一.其本质是JavaScript内部的设计逻辑. 首先看一组代码: <script type="text/javascript"&g ...
- 最简单的Linux下apache+mysql+php安装
转载:http://www.jb51.net/article/29843.htm ubuntu下需要先更新系统后 流程笔记: 1.打开终端,输入“sudo apt-get install apache ...
- Android Studio 修改 包名
Android Studio上修改项目(module)的包名(Package Name) 当你对着包名右击,查找Refactor(重构)下的Rename(快捷键:SHIFT+F6)时,弹出来的仅仅 ...
- SQL的拼接语句在DELPHI中怎么写
SQL 语句的拼接,关键点在于对引号的处理上. 在 delphi 的语法中,使用单引号做字符串的标志符.因此,当遇到 SQL 语句中字符串标识量编写的时候,需要用两个单引号来代替实际的引号. 举例: ...
- HDU4810_Wall Painting
题目很简单. 给你n个数,输出n个答案,第i个答案表示从n个数里取遍i个数的异或值的和. 其实每一个数最多也就32位,把所有的数分解,保存每一位总共有多少个1,最后要是这一位的异或结果为1,那么在所有 ...
- 【bzoj2300】[HAOI2011]防线修建 离线+STL-set维护凸包
题目描述 给你(0,0).(n,0).(x,y)和另外m个点,除(0,0)(n,0)外每个点横坐标都大于0小于n,纵坐标都大于0. 输入 第一行,三个整数n,x,y分别表示河边城市和首都是(0,0), ...