SPOJ DISUBSTR Distinct Substrings 后缀数组
题意:统计母串中包含多少不同的子串
然后这是09年论文《后缀数组——处理字符串的有力工具》中有介绍
公式如下:

原理就是加上新的,减去重的,这题是因为打多校才补的,只能说我是个垃圾
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <utility>
#include <vector>
using namespace std;
typedef long long LL;
const int N = 1e3+;
int cmp(int *r,int a,int b,int l){
return (r[a]==r[b]) && (r[a+l]==r[b+l]);
}
// ???????????????,
// ????????,??????,r[n]=0(??????????)
int wa[N],wb[N],ww[N],wv[N];
int ran[N],height[N];
void DA(int *r,int *sa,int n,int m){ //??N????N??1????????????????CMP???
int i,j,p,*x=wa,*y=wb,*t;
for(i=;i<m;i++) ww[i]=;
for(i=;i<n;i++) ww[x[i]=r[i]]++;
for(i=;i<m;i++) ww[i]+=ww[i-];
for(i=n-;i>=;i--) sa[--ww[x[i]]]=i; //??????1
for(j=,p=;p<n;j*=,m=p) //?????????J?SA???2*J?SA
{
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; //????J??????????
for(i=;i<n;i++) wv[i]=x[y[i]];
for(i=;i<m;i++) ww[i]=;
for(i=;i<n;i++) ww[wv[i]]++;
for(i=;i<m;i++) ww[i]+=ww[i-];
for(i=n-;i>=;i--) sa[--ww[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++; //??????x[],???????
}
}
void calheight(int *r,int *sa,int n){ // ??N?????
int i,j,k=; // height[]?????? 1-N, ??0????????
for(i=;i<=n;i++) ran[sa[i]]=i; // ??SA?RANK
for(i=;i<n; height[ran[i++]] = k ) // ???h[i] = height[ rank[i] ]
for(k?k--:,j=sa[ran[i]-]; r[i+k]==r[j+k]; k++); //?? h[i] >= h[i-1]-1 ?????height??
}
char s[N];
int sa[N],n,r[N],T;
int main(){
scanf("%d",&T);
while(T--){
scanf("%s",s);
n=strlen(s);
for(int i=;i<n;++i)r[i]=(int)s[i];
r[n]=;
DA(r,sa,n+,);
calheight(r,sa,n);
int ans = ;
for(int i=;i<=n;++i)
ans+=n-sa[i]-height[i];
printf("%d\n",ans);
}
return ;
}
SPOJ DISUBSTR Distinct Substrings 后缀数组的更多相关文章
- SPOJ - DISUBSTR Distinct Substrings (后缀数组)
Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...
- spoj 694. Distinct Substrings 后缀数组求不同子串的个数
题目链接:http://www.spoj.com/problems/DISUBSTR/ 思路: 每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数.如果所有的后缀按照su ...
- SPOJ - SUBST1 New Distinct Substrings —— 后缀数组 单个字符串的子串个数
题目链接:https://vjudge.net/problem/SPOJ-SUBST1 SUBST1 - New Distinct Substrings #suffix-array-8 Given a ...
- 【SPOJ – SUBST1】New Distinct Substrings 后缀数组
New Distinct Substrings 题意 给出T个字符串,问每个字符串有多少个不同的子串. 思路 字符串所有子串,可以看做由所有后缀的前缀组成. 按照后缀排序,遍历后缀,每次新增的前缀就是 ...
- SPOJ 694 || 705 Distinct Substrings ( 后缀数组 && 不同子串的个数 )
题意 : 对于给出的串,输出其不同长度的子串的种类数 分析 : 有一个事实就是每一个子串必定是某一个后缀的前缀,换句话说就是每一个后缀的的每一个前缀都代表着一个子串,那么如何在这么多子串or后缀的前缀 ...
- spoj Distinct Substrings 后缀数组
给定一个字符串,求不相同的子串的个数. 假如给字符串“ABA";排列的子串可能: A B A AB BA ABA 共3*(3+1)/2=6种; 后缀数组表示时: A ABA BA 对于A和 ...
- ●SPOJ 8222 NSUBSTR - Substrings(后缀数组)
题链: http://www.spoj.com/problems/NSUBSTR/ 题解: 同届红太阳 --WSY给出的后缀数组解法!!! 首先用倍增算法求出 sa[i],rak[i],hei[i]然 ...
- [spoj694&spoj705]New Distinct Substrings(后缀数组)
题意:求字符串中不同子串的个数. 解题关键:每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数. 1.总数减去height数组的和即可. 注意这里height中为什么不需 ...
- 【SPOJ】Distinct Substrings/New Distinct Substrings(后缀数组)
[SPOJ]Distinct Substrings/New Distinct Substrings(后缀数组) 题面 Vjudge1 Vjudge2 题解 要求的是串的不同的子串个数 两道一模一样的题 ...
随机推荐
- intellij idea 12、13 win8 下 中文输入覆盖的问题(搜狗输入法或者其他输入法)
最近升级到idea12,发现中文输入存在问题,输入中文的时候会出现空格,并且覆盖后面的字符,这个问题让我很郁闷. 假设idea的安装位置为:D:\Program Files\JetBrains\Int ...
- 初识Redis
package com.wangzhu.redis; import java.util.List; import org.junit.After; import org.junit.Before; i ...
- lintcode :Segmemt Tree Build II
题目 Segmemt Tree Build II The structure of Segment Tree is a binary tree which each node has two attr ...
- Vimrc配置以及Vim的常用操作
""""""""""""""""&quo ...
- 259. 3Sum Smaller
题目: Given an array of n integers nums and a target, find the number of index triplets i, j, k with 0 ...
- Servlet小示例:jsp页面提交信息Servlet接收并打印输出
该示例采用doPost方法提交表单,该示例一共包含两个文件. 一个是用来提交用户信息的表单userForm2.jsp,另一个是用来接收参数的Servlet. userForm2.jsp <%@ ...
- IPC$命令详解
一 摘要二 什么是ipc$三 什么是空会话四 空会话可以做什么五 ipc$所使用的端口六 ipc管道在hack攻击中的意义七 ipc$连接失败的常见原因八 复制文件失败的原因九 关于at命令和xp对i ...
- c 语言练习__去掉多余的空白字符_修正
#include <stdio.h> #include <string.h> #include <errno.h> #define BUF_SIZE 128 /* ...
- Linux下拆分大文件
linux split 命令 功能说明:切割文件. 语 法:split [--help][--version][-<行数>][-b <字节>][-C <字节>][- ...
- C++ 11 vlearning
1.新增算术类型 longlong,最小不比long小,一般为64位. 2.列表初始化 int units_sold = {0};或者 int units_sold{0};非11标准 ...