题意:求一个字符串的不重复子串的个数。

分析:对于下标为i的位置,能够产生的前缀子串个数为len-i(下标从0开始),对于与它字典序相邻的后缀产生的子串是重复的(就是他们的最长公共前缀),所以我们要减去这部分重复的,即:len-i-height[i]。

代码实现:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int ws1[],wv[],wa[],wb[];
int rank[],height[],sa[];
char str[]; int 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,*t;
for(i=;i<m;i++)
ws1[i]=;
for(i=;i<n;i++)
ws1[x[i]=r[i]]++;
for(i=;i<m;i++)
ws1[i]+=ws1[i-];
for(i=n-;i>=;i--)
sa[--ws1[x[i]]]=i;
for(j=,p=;p<n;j*=,m=p)
{
for(p=,i=n-j;i<n;i++)
y[p++]=i;
for(i=;i<n;i++)
if(sa[i]>=j)
y[p++]=sa[i]-j;
for(i=;i<n;i++)
wv[i]=x[y[i]];
for(i=;i<m;i++)
ws1[i]=;
for(i=;i<n;i++)
ws1[wv[i]]++;
for(i=;i<m;i++)
ws1[i]+=ws1[i-];
for(i=n-;i>=;i--)
sa[--ws1[wv[i]]]=y[i];
for(t=x,x=y,y=t,p=,x[sa[]]=,i=;i<n;i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
} void calheight(char *r,int *sa,int n)
{
int i,j,k=;
for(i=;i<=n;i++)
rank[sa[i]]=i;
for(i=;i<n;height[rank[i++]]=k)
for(k?k--:,j=sa[rank[i]-];r[i+k]==r[j+k];k++) ;
} int main()
{
int len,i,T;
long long res;
scanf("%d",&T);
getchar();
while(T--)
{
scanf("%s",str);
len=strlen(str);
str[len]=;
da(str,sa,len+,);
calheight(str,sa,len);
res=;
for(i=;i<=len;i++)
res=res+len-sa[i]-height[i];
printf("%lld\n",res);
}
return ;
}

spoj 694(后缀数组)的更多相关文章

  1. SPOJ 694 (后缀数组) Distinct Substrings

    将所有后缀按照字典序排序后,每新加进来一个后缀,它将产生n - sa[i]个前缀.这里和小罗论文里边有点不太一样. height[i]为和字典序前一个的LCP,所以还要减去,最终累计n - sa[i] ...

  2. SPOJ PHRASES 后缀数组

    题目链接:http://www.spoj.com/problems/PHRASES/en/ 题意:给定n个字符串,求一个最长的子串至少在每个串中的不重叠出现次数都不小于2.输出满足条件的最长子串长度 ...

  3. SPOJ REPEATS 后缀数组

    题目链接:http://www.spoj.com/problems/REPEATS/en/ 题意:首先定义了一个字符串的重复度.即一个字符串由一个子串重复k次构成.那么最大的k即是该字符串的重复度.现 ...

  4. SPOJ SUBST1 后缀数组

    题目链接:http://www.spoj.com/problems/SUBST1/en/ 题意:给定一个字符串,求不相同的子串个数. 思路:直接根据09年oi论文<<后缀数组——出来字符串 ...

  5. SPOJ DISUBSTR 后缀数组

    题目链接:http://www.spoj.com/problems/DISUBSTR/en/ 题意:给定一个字符串,求不相同的子串个数. 思路:直接根据09年oi论文<<后缀数组——出来字 ...

  6. Spoj-DISUBSTR - Distinct Substrings~New Distinct Substrings SPOJ - SUBST1~(后缀数组求解子串个数)

    Spoj-DISUBSTR - Distinct Substrings New Distinct Substrings SPOJ - SUBST1 我是根据kuangbin的后缀数组专题来的 这两题题 ...

  7. SPOJ DISUBSTR ——后缀数组

    [题目分析] 后缀数组模板题. 由于height数组存在RMQ的性质. 那么对于一个后缀,与前面相同的串总共有h[i]+sa[i]个.然后求和即可. [代码](模板来自Claris,这个板子太漂亮了) ...

  8. [spoj DISUBSTR]后缀数组统计不同子串个数

    题目链接:https://vjudge.net/contest/70655#problem/C 后缀数组的又一神奇应用.不同子串的个数,实际上就是所有后缀的不同前缀的个数. 考虑所有的后缀按照rank ...

  9. Distinct Substrings SPOJ - DISUBSTR 后缀数组

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

随机推荐

  1. linq中查询列表的使用及iqueryable和list集合之间的转换

    linq中查询列表的使用及iqueryable和list集合之间的转换 比如要查询一个货架集合,但是只需要其id和name即可,可以用以下方法:先写一个model类:CatalogModel(注意该类 ...

  2. ZOJ 3757 Alice and Bob and Cue Sports(模拟)

    题目链接 题意 : 玩台球.Alice 和 Bob,一共可以进行m次,Alice 先打.有一个白球和n个标有不同标号的球,称目标球为当前在桌子上的除了白球以外的数值最小的球,默认白球的标号为0.如果白 ...

  3. ZipArchive框架的文件压缩和解压

    导入第三方框架ZipArchive之后还要在系统库文件中导入一个如下文件(搜索libz出来的任何一个都可以)   导入的头文件是#import "Main.h" 文件压缩 -(vo ...

  4. Win32 SDK程序创建一些控件(简单调用InitCommonControlsEx,并指定ICC_LISTVIEW_CLASSES控件就可以了)

    在Win32 SDK中创建一些控件的时候需要注意一下(具体是哪些控件请参看MSDN文档中列出来的) /* MSDN:Carries information used to load common co ...

  5. RunAsAdmin in windows 8

    function RunAsAdmin(hWnd: HWND; filename: string; Parameters: string): Boolean; { See Step 3: Redesi ...

  6. Entity Framework: Get mapped table name from an entity

    The extension methods I have created one extension method for DbContext and other for ObjectContext: ...

  7. SVN 目录结构

    Subversion有一个很标准的目录结构,是这样的.比如项目是proj,svn地址为svn://proj/,那么标准的svn布局是 svn://proj/|+-trunk+-branches+-ta ...

  8. JS模块化编程

    AMD:异步模块定义,适合客户端环境,不会阻塞运行.客户端受网络影响比较大. CommonJs:适用于服务器端规范,可以同步加载,只受硬盘读写的影响.

  9. POJ 2114 Boatherds【Tree,点分治】

    求一棵树上是否存在路径长度为K的点对. POJ 1714求得是路径权值<=K的路径条数,这题只需要更改一下统计路径条数的函数即可,如果最终的路径条数大于零,则说明存在这样的路径. 刚开始我以为只 ...

  10. Proxifier设置代理

    1.首先需要开启http代理选项---配置文件->高级->HTTP代理服务器,勾选“启用HTTP代理服务器支持” 2.然后开始添加代理服务器选择“配置文件->代理服务器”,在弹出框点 ...