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

假如给字符串“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. nodejs package.json说明

    { "name": "test", //项目名称(必须),由小写英文字母.数字和下划线,不能含空格 "version": "1.0 ...

  2. --1.plsql中学习job

    --1.plsql中学习job --学习job --建表 create table test_job(para_date date); commit; insert into test_job val ...

  3. Oracle时间日期处理方法

    https://www.cnblogs.com/plmm/p/7381496.html 1.用于截取年.月.日.时.分.秒 extract()函数 extract(year from sysdate) ...

  4. openCV图像合成

    #include <iostream> #include <opencv2/opencv.hpp> #include <opencv2/highgui/highgui.h ...

  5. TZ_10_spring-sucrity 服务器和页面的权限控制

    1.在服务器端我们可以通过Spring security提供的注解对方法来进行权限控制. Spring Security在方法的权限控制上支持三种类型的注解,JSR-250注解.@Secured注解和 ...

  6. 用canvas 画出圆形图片

    /** * 把图片处理成圆形,如果不是正方形就按最小边一半为半径处理 * @param {object} imgObj 图片(img)对象 * @param {number} imgType 设置生成 ...

  7. JavaScript--Map,ForEach遍历的比较

    /* forEach只会遍历,不会进行赋值 */ var sum = 0 ; dataArr.forEach(function (value,index,dataArr) { sum +=value. ...

  8. C#中int short Int16 Int32 Int64区别

    Java中没有Int32,Int64,,java中只有int,short,long Java中int就代表Int32 ,short就代表Int16,long就代表Int64 首先,几个基本的关键字: ...

  9. VI/VIM编辑器快捷键

    常用快捷键: Ctrl+f        向下翻页 Ctrl+b       向上翻页 G                移动到文件最后一行 gg              移动到文件第一行 N+回车 ...

  10. SQL Sever实验一 创建和删除数据库数据表

    一. 实验目的 1. 熟悉SQL    Server    2008    中SQL    Server    Management    Studio的环境 2. 了解SQL    Server   ...