题意:

问给定串有多少本质不同的子串?

思路:

子串必是某一后缀的前缀,假如是某一后缀\(sa[k]\),那么会有\(n - sa[k] + 1\)个前缀,但是其中有\(height[k]\)个和上一个重复,那么最终的贡献的新串为\(n - sa[k] + 1 - height[k]\)。故最终结果为\(\sum_{i = 1}^n (n - sa[k] + 1 - height[k])\),即 \(\frac{n * (n + 1)}{2} - \sum_{i = 1}^nheight[k]\)。

参考:

后缀数组——处理字符串的有力工具

代码:

#include<map>
#include<set>
#include<queue>
#include<cmath>
#include<stack>
#include<ctime>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 50000 + 5;
const int INF = 0x3f3f3f3f;
const ull seed = 11;
const int MOD = 1e9 + 7;
using namespace std; int str[maxn];
int t1[maxn], t2[maxn], c[maxn];
int sa[maxn];
int rk[maxn];
int height[maxn];
bool cmp(int *r, int a, int b, int l){
return r[a] == r[b] && r[a + l] == r[b + l];
}
void da(int *str, int n, int m){
n++;
int i, j, p, *x = t1, *y = t2;
for(i = 0; i < m; i++) c[i] = 0;
for(i = 0; i < n; i++) c[x[i] = str[i]]++;
for(i = 1; i < m; i++) c[i] += c[i - 1];
for(i = n - 1; i >= 0; i--) sa[--c[x[i]]] = i;
for(j = 1; j <= n; j <<= 1){
p = 0;
for(i = n - j; i < n; i++) y[p++] = i;
for(i = 0; i < n; i++) if(sa[i] >= j) y[p++] = sa[i] - j;
for(i = 0; i < m; i++) c[i] = 0;
for(i = 0; i < n; i++) c[x[y[i]]]++;
for(i = 1; i < m; i++) c[i] += c[i - 1];
for(i = n - 1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];
swap(x, y);
p = 1; x[sa[0]] = 0;
for(i = 1; i < n; i++)
x[sa[i]] = cmp(y, sa[i - 1], sa[i], j)? p - 1 : p++;
if(p >= n) break;
m = p;
}
int k = 0;
n--;
for(i = 0; i <= n; i++) rk[sa[i]] = i;
for(i = 0; i < n; i++){
if(k) k--;
j = sa[rk[i] - 1];
while(str[i + k] == str[j + k]) k++;
height[rk[i]] = k;
}
}
char s[maxn];
int main(){
int T;
scanf("%d", &T);
while(T--){
scanf("%s", s);
int len = strlen(s);
for(int i = 0; i < len; i++){
str[i] = s[i];
}
s[len] = 0;
da(str, len, 127);
ll n = len;
ll ans = n * (n + 1LL) / 2LL;
for(int i = 1; i <= n; i++){
ans -= height[i];
}
printf("%lld\n", ans);
}
return 0;
}

SPOJ SUBST1 New 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 694 || 705 Distinct Substrings ( 后缀数组 && 不同子串的个数 )

    题意 : 对于给出的串,输出其不同长度的子串的种类数 分析 : 有一个事实就是每一个子串必定是某一个后缀的前缀,换句话说就是每一个后缀的的每一个前缀都代表着一个子串,那么如何在这么多子串or后缀的前缀 ...

  3. spoj 694. Distinct Substrings 后缀数组求不同子串的个数

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

  4. 后缀数组:SPOJ SUBST1 - New Distinct Substrings

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

  5. 【SPOJ – SUBST1】New Distinct Substrings 后缀数组

    New Distinct Substrings 题意 给出T个字符串,问每个字符串有多少个不同的子串. 思路 字符串所有子串,可以看做由所有后缀的前缀组成. 按照后缀排序,遍历后缀,每次新增的前缀就是 ...

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

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

  7. SPOJ - DISUBSTR Distinct Substrings (后缀数组)

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

  8. SPOJ DISUBSTR Distinct Substrings 后缀数组

    题意:统计母串中包含多少不同的子串 然后这是09年论文<后缀数组——处理字符串的有力工具>中有介绍 公式如下: 原理就是加上新的,减去重的,这题是因为打多校才补的,只能说我是个垃圾 #in ...

  9. spoj Distinct Substrings 后缀数组

    给定一个字符串,求不相同的子串的个数. 假如给字符串“ABA";排列的子串可能: A B A AB  BA ABA 共3*(3+1)/2=6种; 后缀数组表示时: A ABA BA 对于A和 ...

随机推荐

  1. 20V,24V转5V,20V,24V转3.3V降压芯片,IC介绍

    常用的20V和24V转5V,3.3V的LDO稳压和DC-DC降压芯片: PW6206系列是一款高精度,高输入电压,低静态电流,高速,低压降线性稳压器具有高纹波抑制.输入电压高达40V,负载电流高达10 ...

  2. Typora+PicGo+Gitee打造图床

    前言 ​ 自己一直使用的是Typora来写博客,但比较麻烦的是图片粘贴上去后都是存储到了本地,写好了之后放到博客园等地,图片不能直接访问,但如今Typora已经支持图片上传,所以搞了一波图片上传到Gi ...

  3. 一文带你看遍 JDK9~14 的重要新特性!

    Java9 发布于 2017 年 9 月 21 日 .作为 Java8 之后 3 年半才发布的新版本,Java 9 带 来了很多重大的变化其中最重要的改动是 Java 平台模块系统的引入,其他还有诸如 ...

  4. 分布式缓存 — kafka

    Kafka是一个分布式.支持分区的(partition).多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性就是可以实时的处理大量数据以满足各种需求场景:比如基于h ...

  5. MySQL 数据库性能调优

    MySQL 数据库性能调优 MySQL性能 最大数据量 最大并发数 优化的范围有哪些 存储.主机和操作系统方面: 应用程序方面: 数据库优化方面: 优化维度 数据库优化维度有四个: 优化选择: 数据库 ...

  6. BGP总结(一)

    0.AS 狭义:在RIP.OSPF和EIGRP等IGP协议中,AS表示只运行此单种协议的路由域 广义:运行多个IGP协议的路由域,多个IGP协议之间通过路由重发布来实现通信,AS和AS之间通过BGP来 ...

  7. Java数组模拟队列 + 优化

    队列介绍 队列是一个有序列表,可以用数组或是链表来实现. 遵循先入先出的原则. 即:先存入队列的数据,要先取出.后存入的要后取出 示意图:(使用数组模拟队列示意图)  数组模拟队列 队列本身是有序列表 ...

  8. docker(8)Dockerfile指令介绍

    前言 Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明. Dockerfile简介 Dockerfile是用来构建Docker镜像的构建文件,是由一系列 ...

  9. vue开发东京买菜,全栈项目,前端django,带手机GPS精准定位,带发票系统,带快递系统,带微信/支付宝/花呗/银行卡支付/带手机号一键登陆,等等

    因为博客园不能发视频,所以,完整的视频,开发文档,源码,请向博主索取 完整视频+开发文档+源码,duanshuiLu.com下载 vue+django手机购物商城APP,带支付,带GPS精准定位用户, ...

  10. Hadoop----hdfs dfs常用命令的使用

    用法    -mkdir    创建目录    Usage:hdfs dfs -mkdir [-p] < paths>    选项:-p    很像Unix mkdir -p,沿路径创建父 ...