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

分析:对于下标为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. [转]HttpClient的超时用法小记

    HttpClient的超时用法小记 HttpClient在使用中有两个超时时间,是一直接触和使用的,由于上次工作中使用httpClient造成了系统悲剧的情况,特地对它的两个超时时间进行了小小的测试, ...

  2. lintcode :Permutation Index 排列序号

    题目: 排列序号 给出一个不含重复数字的排列,求这些数字的所有排列按字典序排序后该排列的编号.其中,编号从1开始. 样例 例如,排列[1,2,4]是第1个排列. 解题: 这个题目感觉很坑的.感觉这只有 ...

  3. lintcode :Remove Duplicates from Sorted List 删除排序链表中的重复元素

    题目: 删除排序链表中的重复元素 给定一个排序链表,删除所有重复的元素每个元素只留下一个.   您在真实的面试中是否遇到过这个题? 样例 给出1->1->2->null,返回 1-& ...

  4. 【memcache缓存专题(3)】PHP-memcache扩展的安装以及使用

    安装PHP-memcache扩展和安装其他PHP扩展的步骤是一样的. 安装 step 1:搜索下载扩展 http://pecl.php.net/package/memcache step 2: gzi ...

  5. PHP中的多态

    多态的概念一般是强类型语言来谈的,因为强类型语言它必须要声明参数类型,比如一个手电筒对象的打开方法其参数申明了只能是蓝光,就不能传其他光.但可以用父类渲染的方式使其多态,比如声明一个光的父类,让其它颜 ...

  6. iOS xcuserdata

    说明:       project.xcworkspace说明:is a directory of files describing the workspace or projects. Althou ...

  7. [iOS]修改开发者中心Bundle Identifier的一些配置

    登录开发者中心https://developer.apple.com 然后找到你的Bundle Identifier. 这里暂时只讲开启推送的功能,如果需要别的直接勾选前面的选择框 然后拉到最下面点击 ...

  8. 259. 3Sum Smaller

    题目: Given an array of n integers nums and a target, find the number of index triplets i, j, k with 0 ...

  9. OpenCV源码阅读(3)---base.hpp

    base.h处于core模块中,是OpenCV的核心类.其作用是定义了OpenCV的基本错误类型,在程序运行出现错误是抛出错误,防止数据溢出.总而言之,其功能主要是考虑程序的健壮性. 头文件 #ifn ...

  10. C# 使用ManualResetEvent 进行线程同步

    上一篇我们介绍了AutoResetEvent,这一篇我们来看下ManualResetEvent ,顾名思义ManualResetEvent  为手动重置事件. AutoResetEvent和Manua ...