Tyvj传送门

luogu传送门

经典题

统计一个字符串中不同子串的个数

一个字符串中的所有子串就是所有后缀的前缀

先求出后缀数组,求出后缀数组中相邻两后缀的 lcp

那么按照后缀数组中的顺序遍历求解

每一个后缀 suffix(sa[i]) 对于答案的贡献为 len - sa[i] - height[i]

len - sa[i] 为当前后缀的长度,也就是当前后缀所有前缀的个数(字符串从 0 开始)

height[i] 就是相邻两后缀 lcp,因为有可能会有相同前缀,而相同前缀在前面已经计算过了

为什么只需要 height 数组,而不用把任意两后缀的 lcp 求出来呢?

因为所有后缀已经按照字典序排序了,也就是说,sa[i] 和 sa[i - 1] 的 lcp 即为 sa[i] 和 sa[0 ~ i - 1] 的所有 lcp 的最大值。

——代码(Tyvj)

 #include <cstdio>
#include <cstring>
#include <iostream>
#define N 200001
#define LL long long LL ans;
int len, m = ;
int buc[N], x[N], y[N], sa[N], rank[N], height[N];
char s[N]; inline void build_sa()
{
int i, k, p;
for(i = ; i < m; i++) buc[i] = ;
for(i = ; i < len; i++) buc[x[i] = s[i]]++;
for(i = ; i < m; i++) buc[i] += buc[i - ];
for(i = len - ; i >= ; i--) sa[--buc[x[i]]] = i;
for(k = ; k <= len; k <<= )
{
p = ;
for(i = len - ; i >= len - k; i--) y[p++] = i;
for(i = ; i < len; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
for(i = ; i < m; i++) buc[i] = ;
for(i = ; i < len; i++) buc[x[y[i]]]++;
for(i = ; i < m; i++) buc[i] += buc[i - ];
for(i = len - ; i >= ; i--) sa[--buc[x[y[i]]]] = y[i];
std::swap(x, y);
p = , x[sa[]] = ;
for(i = ; i < len; i++)
x[sa[i]] = y[sa[i - ]] == y[sa[i]] && y[sa[i - ] + k] == y[sa[i] + k] ? p - : p++;
if(p >= len) break;
m = p;
}
} inline void build_height()
{
int i, j, k = ;
for(i = ; i < len; i++) rank[sa[i]] = i;
for(i = ; i < len; i++)
{
if(!rank[i]) continue;
if(k) k--;
j = sa[rank[i] - ];
while(s[i + k] == s[j + k] && i + k < len && j + k < len) k++;
height[rank[i]] = k;
}
} int main()
{
int i;
scanf("%d", &len);
getchar();
for(i = ; i < len; i++)
{
s[i] = getchar();
if((i + ) % == ) getchar();
}
build_sa();
build_height();
for(i = ; i < len; i++) ans += (LL)(len - sa[i] - height[i]);
printf("%lld\n", ans);
return ;
}

洛谷那题好像数据有点问题。

[TyvjP1515] 子串统计 [luoguP2408] 不同子串个数(后缀数组)的更多相关文章

  1. 洛谷P2408 不同子串个数 后缀数组 + Height数组

    ## 题目描述: 给你一个长为 $N$ $(N<=10^5)$ 的字符串,求不同的子串的个数我们定义两个子串不同,当且仅当有这两个子串长度不一样 或者长度一样且有任意一位不一样.子串的定义:原字 ...

  2. LUOGU P2408 不同子串个数(后缀数组)

    传送门 解题思路 后缀数组求本质不同串的裸题.\(ans=\dfrac{n(n+1)}{2} -\sum height[i]\). 代码 #include<iostream> #inclu ...

  3. 洛谷P2408 不同字串个数 [后缀数组]

    题目传送门 不同字串个数 题目背景 因为NOI被虐傻了,蒟蒻的YJQ准备来学习一下字符串,于是它碰到了这样一道题: 题目描述 给你一个长为N的字符串,求不同的子串的个数 我们定义两个子串不同,当且仅当 ...

  4. POJ 3415 Common Substrings(长度不小于K的公共子串的个数+后缀数组+height数组分组思想+单调栈)

    http://poj.org/problem?id=3415 题意:求长度不小于K的公共子串的个数. 思路:好题!!!拉丁字母让我Wa了好久!!单调栈又让我理解了好久!!太弱啊!! 最简单的就是暴力枚 ...

  5. bzoj 1396: 识别子串 && bzoj 2865: 字符串识别【后缀数组+线段树】

    根据height数组的定义,和当前后缀串i最长的相同串的长度就是max(height[i],height[i+1]),这个后缀贡献的最短不同串长度就是len=max(height[i],height[ ...

  6. POJ2774 Long Long Message —— 后缀数组 两字符串的最长公共子串

    题目链接:https://vjudge.net/problem/POJ-2774 Long Long Message Time Limit: 4000MS   Memory Limit: 131072 ...

  7. 【SPOJ – REPEATS】 后缀数组【连续重复子串】

    字体颜色如何 字体颜色 SPOJ - REPEATS 题意 给出一个字符串,求重复次数最多的连续重复子串. 题解 引自论文-后缀数组--处理字符串的有力工具. 解释参考博客 "S肯定包括了字 ...

  8. UOJ #35. 后缀排序[后缀数组详细整理]

    #35. 后缀排序 统计 描述 提交 自定义测试 这是一道模板题. 读入一个长度为 nn 的由小写英文字母组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符 ...

  9. 后缀数组 --- HDU 3518 Boring counting

    Boring counting Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=3518 Mean: 给你一个字符串,求:至少出 ...

随机推荐

  1. 【转载】同步与异步--阻塞与非阻塞型I/O

    同步阻塞IO 在这个模型中,应用程序(application)为了执行这个read操作,会调用相应的一个system call,将系统控制权交给kernel,然后就进行等待(这其实就是被阻塞了).ke ...

  2. 使用GitHub(转载)

    转自:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/00137628548491 ...

  3. Kafka详解与总结(三)

    Kafka分片存储机制 几个kafka重要概念: Broker:消息中间件处理结点,一个Kafka节点就是一个broker,多个broker可以组成一个Kafka集群. Topic:一类消息,例如pa ...

  4. Tempter of the Bone------剪枝

    看了好多别人的  代码,最终还是 感觉 这种代码的风格适合我  下面附上代码 /* 首先 应该充满信心! 先写出来 自己的程序 然后慢慢改 , 如果是 答题思路错误的话 借鉴别人的 代码 再写 */ ...

  5. 记一次Oracle冷备恢复的过程

    一.故障来临 某日中午,市电意外中断,机房UPS电源由于负载过重而未接管供电,所有服务器全部重启...... 待所有服务器重启后,正在逐一检查设备和业务运行情况时,意外发生了.一台年代久远的HP PC ...

  6. C与C艹的内存管理方式

    C 内存开辟出的空间一般可以分成:代码段,数据段(初始化的数据段, 为初始化的数据段BSS),堆,栈 代码段:保存程序文本,指令指针EIP就是指向代码段,可读可执行不可写 数据段:保存初始化的全局变量 ...

  7. android黑科技系列——获取加固后应用App的所有方法信息

    一.前言 在逆向应用的时候,我们有时候希望能够快速定位到应用的关键方法,在之前我已经详细介绍了一个自己研发的代码动态注入工具icodetools,来进行动态注入日志信息到应用中,不了解的同学可以查看这 ...

  8. Ajax——模板引擎

    模板介绍 1.必要性:ajax请求从服务器接收到大量数据,此时再用普通的字符串拼接是很耗费时间的,这时候模板就有其必要性 2.便利性:插件套用,现在有很多主流的模板插件:BaiduTemplate(百 ...

  9. JS——this与new

    this: 1.this只出现在函数中 2.谁调用函数,this就指的是谁 3.new People的this指的就是被创建的对象实例 new: 1.开辟内存空间,存储新创建的对象 2.把this设置 ...

  10. CSS3利用box-shadow实现相框效果

    CSS3利用box-shadow实现相框效果 <style> html { overflow: hidden; background-color: #653845; background- ...