给定一个字符串,求不相同的子串的个数。

假如给字符串“ABA";排列的子串可能:

A       B      A

AB       BA

ABA  

共3*(3+1)/2=6种;

后缀数组表示时:

A

ABA

BA

对于A和AB height[i]=1;

表明一个长度公共,所以ABA中多出现了A这个子串,所以6-1=5;

对于ABA BA height[i]=0,所以不需要减去。

最后答案为5;

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<string>
#include<map>
#define LL long long
using namespace std;
#define maxn 1100
int wa[maxn],wb[maxn],wv[maxn],WS[maxn];
int cmp(int *r,int a,int b,int l)
{return r[a]==r[b]&&r[a+l]==r[b+l];}
void da(int *r,int *sa,int n,int m)
{
int i,j,p,*x=wa,*y=wb,*t;
for(i=;i<m;i++) WS[i]=;
for(i=;i<n;i++) WS[x[i]=r[i]]++;
for(i=;i<m;i++) WS[i]+=WS[i-];
for(i=n-;i>=;i--) sa[--WS[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++) WS[i]=;
for(i=;i<n;i++) WS[wv[i]]++;
for(i=;i<m;i++) WS[i]+=WS[i-];
for(i=n-;i>=;i--) sa[--WS[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++;
}
return;
}
int Rank[maxn],height[maxn];
void calheight(int *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++);
return;
}
int r[maxn],sa[maxn];
char s[maxn];
void slove(int len)
{
int i,j,ans;
ans=(len+)*len/;//总共排列的个数
for(i=;i<=len;i++)
{
ans-=height[i];//相同的部分长度表示这段重复出现了。并且出现了height[i]个组合。
}
cout<<ans<<endl;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>s;
int len=strlen(s);
for(int i=;i<len;i++)
r[i]=s[i];
r[len]=;
da(r,sa,len+,);
calheight(r,sa,len);
slove(len);
}
}

spoj 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 694. Distinct Substrings 后缀数组求不同子串的个数

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

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

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

  8. SPOJ_705_New Distinct Substrings_后缀数组

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

  9. SPOJ Distinct Substrings(后缀数组求不同子串个数,好题)

    DISUBSTR - Distinct Substrings no tags  Given a string, we need to find the total number of its dist ...

随机推荐

  1. finger 工具:用来查询用户信息,侧重用户家目录、登录SHELL等

    finger 工具侧重于用户信息的查询:查询的内容包括用户名(也被称为登录名Login),家目录,用户真实的名字(Name)... ... 办公地址.办公电话:也包括登录终端.写状态.空闭时间等: 我 ...

  2. [mybatis]Example的用法 标签: mybatis 2017-05-21 21:46 651人阅读 评论(11)

    Example类是什么? Example类指定如何构建一个动态的where子句. 表中的每个non-BLOB列可以被包括在where子句中. 例子是展示此类用法的最好方式. Example类可以用来生 ...

  3. myql 配置项

    提高数据插入速度方法 bulk_insert_buffer_size 默认:8M (8*1024*1024) 参考网址:https://stackoverflow.com/questions/2030 ...

  4. 数组的方法之(Array.prototype.forEach() 方法)

    forEach() 方法对数组的每个元素执行一次提供的函数. 注意: 没有返回一个新数组 并且 没有返回值! 应用场景:为一些相同的元素,绑定事件处理器! const arr = ['a', 'b', ...

  5. Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---状态模式[转]

    {没有应用状态模式的代码} //工程文件 program Project1; {$APPTYPE CONSOLE} uses  uGumballMachine in 'uGumballMachine. ...

  6. Django+小程序技术打造微信小程序助手

    Django+小程序技术打造微信小程序助手   整个课程都看完了,当前这个课程的分享可以往下看,下面有某盘的链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,同时也分享下自己的总结 ...

  7. Django--登录功能

    登录功能: 1.路由访问如果不加斜杠,内部会重定向加斜杠的路由 所有的html文件都默认卸载templates文件夹下面 所有的(css,js,前端第三方的类库)默认都放在static文件夹下 htm ...

  8. 集训队日常训练20180518-DIV2

    A.3232 n个物品,换取要花积分,问刚好花完积分能换最大多少价值的物品. 多重背包. #include <bits/stdc++.h> using namespace std; ]; ...

  9. 洛谷P1774 最接近神的人_NOI导刊2010提高(02) [2017年6月计划 线段树03]

    P1774 最接近神的人_NOI导刊2010提高(02) 题目描述 破解了符文之语,小FF开启了通往地下的道路.当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古代人进行某种活动的图案.而石门 ...

  10. 洛谷P1082 同余方程 [2012NOIP提高组D2T1] [2017年6月计划 数论06]

    P1082 同余方程 题目描述 求关于 x 的同余方程 ax ≡ 1 (mod b)的最小正整数解. 输入输出格式 输入格式: 输入只有一行,包含两个正整数 a, b,用一个空格隔开. 输出格式: 输 ...