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. webrtc doubango linphone

    1.doubango官网:http://www.doubango.org/ 2.doubango是一个开源的VOIP基础平台, 并能用于嵌入式和桌面系统的开源框架,该框架使用ANSCI-C编写,具有很 ...

  2. 机器学习:模型泛化(岭回归:Ridge Regression)

    一.基础理解 模型正则化(Regularization) # 有多种操作方差,岭回归只是其中一种方式: 功能:通过限制超参数大小,解决过拟合或者模型含有的巨大的方差误差的问题: 影响拟合曲线的两个因子 ...

  3. Python 中的0 和 1 的意思

    Python程序语言指定任何非0和非空(null)值为true,0 或者 null为false,所以Python中的 1 代表 True,0代表False

  4. HAproxy+Mycat

    haproxy+mycat搭建haproxy server 10.0.1.134mycat server 10.0.1.134,10.0.1.135mysql master 10.0.1.134mys ...

  5. ruby中nil?, empty? and blank?

    In Ruby, you check with nil? if an object is nil: article = nil article.nil? # => true empty? che ...

  6. c#学习之路---壁咚漏洞搜索

    每次出漏洞都会用JAVA去写,不过JAVA你懂得,写GUI每次画图很吃力. 于是左右学习了下c#,期间也得到表哥storm7kb的帮助,要不然这个表格与数据绑定不知道c#怎么弄. 上一下图吧: --- ...

  7. Install boot2docker defaule username and password

    username passowrd method docker tcuser ssh root   command sudo -i

  8. Ettercap进行arp毒化

    攻击者IP:192.168.220.152 受害者IP:192.168.220.151 网关:192.168.220.2 修改DNS文件 ┌─[root@sch01ar]─[~] └──╼ #vim ...

  9. 2014.10.1 Cmd更改系统时间

    Process p = new Process(); //Process类有一个StartInfo属性 //设定程序名 p.StartInfo.FileName = "cmd.exe&quo ...

  10. 球的移动(move)

    有n个盒子(1<=N<=1000)围成一个圈,每个盒子有ai个球,所有盒子的球的总数小于等于n.每一次移动,可以把一个球移动到它的一个相邻的盒子内.现在要使得每个盒子的球数<=1,求 ...