New Distinct Substrings(后缀数组)

给定一个字符串,求不相同的子串的个数。\(n<=50005\)。

显然,任何一个子串一定是后缀上的前缀。先(按套路)把后缀排好序,对于当前的后缀\(S_i\),显然他有\(n-sa[i]\)个前缀。其中,有\(height[i]\)个前缀字符串在编号比它小的后缀中出现过,因此它对答案的贡献是\(n-sa[i]-height[i]\)。

#include <cstdio>
#include <cstring>
using namespace std; const int maxn=50005;
int T, n, m=maxn;
char s[maxn]; bool cmp(int *r, int a, int b, int j){
return r[a]==r[b]&&r[a+j]==r[b+j]; }
int *x, *y, *t, wa[maxn], wb[maxn], ws[maxn], sa[maxn], wv[maxn], ht[maxn];
void Suffixsort(char *r){
int i, j, p=0; x=wa, y=wb; m=maxn;
for (i=0; i<m; ++i) ws[i]=0;
for (i=0; i<n; ++i) ++ws[x[i]=r[i]];
for (i=1; i<m; ++i) ws[i]+=ws[i-1];
for (i=0; i<n; ++i) sa[--ws[r[i]]]=i;
for (j=1; p<n&&j<n; j<<=1, m=p+1){
for (p=0, i=n-j; i<n; ++i) y[p++]=i;
for (i=0; i<n; ++i) if (sa[i]>=j) y[p++]=sa[i]-j;
for (i=0; i<n; ++i) wv[i]=x[y[i]];
for (i=0; i<m; ++i) ws[i]=0;
for (i=0; i<n; ++i) ++ws[x[i]];
for (i=1; i<m; ++i) ws[i]+=ws[i-1];
for (i=n-1; i>0; --i) sa[--ws[wv[i]]]=y[i]; //这句话依然是背下来的
t=x; x=y; y=t; x[sa[0]]=1;
for (p=1, i=1; i<n; ++i)
x[sa[i]]=cmp(y, sa[i-1], sa[i], j)?p:++p; //+1
}
memset(ht, 0, sizeof(ht));
for (int i=0; i<n; ++i) --x[i]; p=0;
for (int i=0; i<n; ht[x[i++]]=p){
if (!x[i]) continue;
for (p?p--:0, j=sa[x[i]-1]; r[i+p]==r[j+p]&&i+p<n; ++p);
} ht[0]=0;
return;
} int main(){
scanf("%d", &T); int ans;
while (T--) {
scanf("%s", s); n=strlen(s);
Suffixsort(s); ans=0;
//for (int i=0; i<n; ++i) printf("%d ", sa[i]); puts("");
//for (int i=1; i<n; ++i) printf("%d ", ht[i]);
for (int i=0; i<n; ++i)
ans+=n-sa[i]-ht[i];
printf("%d\n", ans);
}
return 0;
}

New Distinct Substrings(后缀数组)的更多相关文章

  1. SPOJ - SUBST1 New Distinct Substrings —— 后缀数组 单个字符串的子串个数

    题目链接:https://vjudge.net/problem/SPOJ-SUBST1 SUBST1 - New Distinct Substrings #suffix-array-8 Given a ...

  2. SPOJ - DISUBSTR Distinct Substrings (后缀数组)

    Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...

  3. 【SPOJ – SUBST1】New Distinct Substrings 后缀数组

    New Distinct Substrings 题意 给出T个字符串,问每个字符串有多少个不同的子串. 思路 字符串所有子串,可以看做由所有后缀的前缀组成. 按照后缀排序,遍历后缀,每次新增的前缀就是 ...

  4. SPOJ DISUBSTR Distinct Substrings 后缀数组

    题意:统计母串中包含多少不同的子串 然后这是09年论文<后缀数组——处理字符串的有力工具>中有介绍 公式如下: 原理就是加上新的,减去重的,这题是因为打多校才补的,只能说我是个垃圾 #in ...

  5. SPOJ 694 || 705 Distinct Substrings ( 后缀数组 && 不同子串的个数 )

    题意 : 对于给出的串,输出其不同长度的子串的种类数 分析 : 有一个事实就是每一个子串必定是某一个后缀的前缀,换句话说就是每一个后缀的的每一个前缀都代表着一个子串,那么如何在这么多子串or后缀的前缀 ...

  6. spoj Distinct Substrings 后缀数组

    给定一个字符串,求不相同的子串的个数. 假如给字符串“ABA";排列的子串可能: A B A AB  BA ABA 共3*(3+1)/2=6种; 后缀数组表示时: A ABA BA 对于A和 ...

  7. [spoj694&spoj705]New Distinct Substrings(后缀数组)

    题意:求字符串中不同子串的个数. 解题关键:每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数. 1.总数减去height数组的和即可. 注意这里height中为什么不需 ...

  8. spoj 694. Distinct Substrings 后缀数组求不同子串的个数

    题目链接:http://www.spoj.com/problems/DISUBSTR/ 思路: 每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数.如果所有的后缀按照su ...

  9. SPOJ_705_New Distinct Substrings_后缀数组

    SPOJ_705_New Distinct Substrings_后缀数组 题意: 给定一个字符串,求该字符串含有的本质不同的子串数量. 后缀数组的一个小应用. 考虑每个后缀的贡献,如果不要求本质不同 ...

  10. SPOJ- Distinct Substrings(后缀数组&后缀自动机)

    Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...

随机推荐

  1. 关于java.lang.ClassNotFoundException

    关于java.lang.ClassNotFoundException,在自己的程序中,也出现过好几次了,每次找到原因之后,又会发觉原来是以前处理过的. java.lang.ClassNotFoundE ...

  2. 关于web.xml不同版本之间的区别

    一.Servlet 2.3 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3// ...

  3. AngularJS中的http服务的简单用法

    我们可以使用内置的$http服务直接同外部进行通信.$http服务只是简单的封装了浏览器原生的XMLHttpRequest对象. 1.链式调用 $http服务是只能接受一个参数的函数,这个参数是一个对 ...

  4. Oracle 备份与恢复基础

    Oracle 备份与恢复基础 :三思笔记 备份与恢复 A whole database backup is either a consistent backup or an inconsistent ...

  5. throw和throws的区别和联系

    突然发现今天诗兴大发,看来又得写点内容了. throw和throws对于Java程序员而言它们真的不是很陌生.但对于我这样的选手而言一提到它们的区别和联系就蒙圈了... 为了以后不蒙圈,今天就研究一下 ...

  6. “百度杯”CTF比赛 十一月场(Misc)

    签到题: 题目提示: 文件在i春秋的ctf2群里,加群下载文件 下载下来之后发现有压缩密码 题目提示有提示解压密码:key:ichunqiumemeda 打开文件,得到flag 签到题2: 点击下载附 ...

  7. Oracle 设置主键自增长__Oracle

    转自:https://yq.aliyun.com/ziliao/258074 如果想在Oracle数据库里实现数据表主键自增,我们似乎没有办法像MySql般直接定义列的属性来实现.不过对于这个数据库的 ...

  8. Java Swing 如何让窗体居中显示

    如题,其他不多说,直接上代码! package com.himarking.tool; import java.awt.Toolkit; import javax.swing.JFrame; @Sup ...

  9. 【263】Linux 添加环境变量 & 全局 shell 脚本

    Linux电脑添加环境变量 方法一:通过修改 profile 文件添加环境变量 1. 打开终端,输入[vi /etc/profile],如下所示,点击回车 [ocean@ygs-jhyang-w1 L ...

  10. JAVA基础知识总结10(包类)

    包:定义包用package关键字. 1:对类文件进行分类管理. 2:给类文件提供多层名称空间. 如果生成的包不在当前目录下,需要最好执行classpath,将包所在父目录定义到classpath变量中 ...