题目链接

题目描述

给定一个长度为 n 的字符串 S,令 Ti 表示它从第 i 个字符开始的后缀。求

\(\sum_{1\le i <j\le n}len(T_i)+len(T_j)-2*lcp(T_i,T_j)\)

说明

对于 100% 的数据,保证 2⩽n⩽500000,且均为小写字母。

思路

注意到前面那个东西是个定值,所以关键在于如何求后面那个东西

由于 \(lcp(sa[l],sa[r])=min_{i=l+1}^{r}H[i]\)

所以后面那个东西实际上就是 \(H\) 数组的所有子区间 \(min\) 之和,当然是去掉 \(H[1]\) 之后

这个东西可以用单调栈通过维护后缀 \(min\) 来求

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 500010
#define INF 1000000000
#define ll long long
using namespace std; int n; char c[maxn]; int tax[maxn], rk[maxn], tp[maxn], sa[maxn], M = 200;
void rsort() {
for (int i = 0; i <= M; ++i) tax[i] = 0;
for (int i = 1; i <= n; ++i) ++tax[rk[i]];
for (int i = 1; i <= M; ++i) tax[i] += tax[i - 1];
for (int i = n; i; --i) sa[tax[rk[tp[i]]]--] = tp[i];
} int c1, H[maxn];
void SA(char *s) {
for (int i = 1; i <= n; ++i) rk[i] = s[i], tp[i] = i; rsort();
for (int k = 1; k < n; k *= 2) {
if (c1 == n) break; M = c1; c1 = 0;
for (int i = n - k + 1; i <= n; ++i) tp[++c1] = i;
for (int i = 1; i <= n; ++i) if (sa[i] > k) tp[++c1] = sa[i] - k;
rsort(); swap(tp, rk); rk[sa[1]] = c1 = 1;
for (int i = 2; i <= n; ++i) {
if (tp[sa[i - 1]] != tp[sa[i]] || tp[sa[i - 1] + k] != tp[sa[i] + k]) ++c1;
rk[sa[i]] = c1;
}
} int lcp = 0;
for (int i = 1; i <= n; ++i) {
if (lcp) --lcp;
int j = sa[rk[i] - 1];
while (s[j + lcp] == s[i + lcp]) ++lcp;
H[rk[i]] = lcp;
}
} int st[maxn], top; ll ans, s;
int main() {
scanf("%s", c + 1); n = strlen(c + 1); SA(c); ans = (ll) n * (n - 1) / 2 * (n + 1);
for (int i = 1; i < n; ++i) H[i] = H[i + 1]; H[n--] = 0;
for (int i = 1; i <= n; ++i) {
while (top && H[st[top]] >= H[i]) {
s -= (ll) (st[top] - st[top - 1]) * H[st[top]];
--top;
}
st[++top] = i; s += (st[top] - st[top - 1]) * H[st[top]];
ans -= 2 * s;
} cout << ans << endl;
return 0;
}

【后缀数组】【LuoguP4248】 [AHOI2013]差异的更多相关文章

  1. luoguP4248 [AHOI2013]差异

    题意 考虑式子前面那段其实是\((n-1)*\frac{n*(n+1)}{2}\),因为每个后缀出现了\(n-1\)次,后缀总长为\(\frac{n*(n+1)}{2}\). 现在考虑后面怎么求: \ ...

  2. BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈

    BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao ...

  3. bzoj 3238: [Ahoi2013]差异 -- 后缀数组

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Description Input 一行,一个字符串S Output 一行,一个 ...

  4. 【BZOJ3238】[Ahoi2013]差异 后缀数组+单调栈

    [BZOJ3238][Ahoi2013]差异 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Ou ...

  5. [bzoj3238][Ahoi2013]差异_后缀数组_单调栈

    差异 bzoj-3238 Ahoi-2013 题目大意:求任意两个后缀之间的$LCP$的和. 注释:$1\le length \le 5\cdot 10^5$. 想法: 两个后缀之间的$LCP$和显然 ...

  6. [AHOI2013] 差异 - 后缀数组,单调栈

    [AHOI2013] 差异 Description 求 \(\sum {len(T_i) + len(T_j) - 2 lcp(T_i,T_j)}\) 的值 其中 \(T_i (i = 1,2,... ...

  7. BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2326  Solved: 1054[Submit][Status ...

  8. [BZOJ3238][Ahoi2013]差异解题报告|后缀数组

    Description 先分析一下题目,我们显然可以直接算出sigma(len[Ti]+len[Tj])的值=(n-1)*n*(n+1)/2 接着就要去算这个字符串中所有后缀的两两最长公共前缀总和 首 ...

  9. 【bzoj3238】差异[AHOI2013](后缀数组+单调栈)

    题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3238 这道题从大概半年以前就开始啃了,不过当时因为一些细节没调出来,看了Sakits神犇 ...

  10. BZOJ3238 [Ahoi2013]差异 【后缀数组 + 单调栈】

    题目链接 BZOJ3238 题解 简单题 经典后缀数组 + 单调栈套路,求所有后缀\(lcp\) #include<iostream> #include<cstdio> #in ...

随机推荐

  1. The One day 中位数的计算

    """ 中位数是有序列表中间的数.如果列表长度是偶数,中位数则是中间两个数的平均值. 例如, [2,3,4] 的中位数是 3 [2,3] 的中位数是 (2 + 3) / ...

  2. Java—十进制数对n进制数转换

    import java.math.BigInteger;import java.util.Scanner; /** * @auther Aohui * @create 2019-11-06-15:33 ...

  3. Java之路---Day01

    2019-10-17-19:36:43 标识符: 标识符:是指在程序中,自己定义的内容.如:类名.方法名.变量名等 命名规则(硬性要求): 1.有英文字母(区分大小写).数字.$(美元符)._(下划线 ...

  4. 图解HTTP(二)

    第四章 返回结果的HTTP状体码 1.状态码告知从服务器返回的结果   类别 原因短语 1XX Infomational信息性状态码 接收的请求正在处理中 2XX Success成功状态码 请求正常处 ...

  5. python系列:二、Urllib库的高级用法

    1.设置Headers 有些网站不会同意程序直接用上面的方式进行访问,如果识别有问题,那么站点根本不会响应,所以为了完全模拟浏览器的工作,我们需要设置一些Headers 的属性. 打开我们的浏览器,调 ...

  6. shell输出文本颜色

    绿地白字 echo -e "\033[42;37m 绿底白字 \033[0m"

  7. Kali Linux 2019.4发布了!解决Kali Linux 2019.4中文乱码问题

    2019年11月26日,kali Linux官网发布了Kali Linux 2019.4发行版,此版本做了很大的改动,界面焕然一新. Kali Linux 2019.4涉及到的一些新更新内容包括: 新 ...

  8. 面试中的nginx高可用高并发!

    本文转自:91博客:原文地址:http://www.9191boke.com/439923471.html 面试题: nginx高可用?nginx 是如何实现并发的?为什么nginx不使用多线程?ng ...

  9. pycharm新建项目后按钮灰色问题

    同样适用于导入别人的新项目后无法运行问题 原因一: pycharm没有设置系统解析器 解决方法一: 打开pycharm->File->Settings->Project Interp ...

  10. Python并发编程-并发解决方案概述

    Python并发编程-并发解决方案概述 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.并发和并行区别 1>.并行(parallel) 同时做某些事,可以互不干扰的同一个时 ...