题目链接:BZOJ - 3238

题目分析

显然,这道题就是求任意两个后缀之间的LCP的和,这与后缀数组的联系十分明显。

求出后缀数组后,求出字典序相邻两个后缀的LCP,即 Height 数组。

那么我们可以用这个 Height 数组求出所有后缀之间 LCP 的和。

我们用 f[i] 表示字典序第 i 的后缀与字典序在 i 之后的所有后缀的 LCP 的和。

我们知道,两个后缀的 LCP 为 Height 数组中这两个后缀之间的最小值。

我们从最后向前推 i ,用一个单调栈维护后面的 Height 单调不上升,然后用 St[Top] 来推 f[i] 即可,具体见代码。

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm> using namespace std; const int MaxL = 500000 + 5; typedef long long LL; LL Ans, Temp;
LL f[MaxL]; int n, Top;
int A[MaxL], Rank[MaxL], SA[MaxL], Height[MaxL], St[MaxL];
int VA[MaxL], VB[MaxL], VC[MaxL], Sum[MaxL]; char S[MaxL]; inline bool Cmp(int *a, int x, int y, int l) {
return (a[x] == a[y]) && (a[x + l] == a[y + l]);
} void DA(int *A, int n, int m) {
int *x, *y, *t;
x = VA; y = VB;
for (int i = 1; i <= m; ++i) Sum[i] = 0;
for (int i = 1; i <= n; ++i) ++Sum[x[i] = A[i]];
for (int i = 2; i <= m; ++i) Sum[i] += Sum[i - 1];
for (int i = n; i >= 1; --i) SA[Sum[x[i]]--] = i;
int p, q;
p = 0;
for (int j = 1; p < n; j <<= 1, m = p) {
q = 0;
for (int i = n - j + 1; i <= n; ++i) y[++q] = i;
for (int i = 1; i <= n; ++i) {
if (SA[i] <= j) continue;
y[++q] = SA[i] - j;
}
for (int i = 1; i <= m; ++i) Sum[i] = 0;
for (int i = 1; i <= n; ++i) VC[i] = x[y[i]];
for (int i = 1; i <= n; ++i) ++Sum[VC[i]];
for (int i = 2; i <= m; ++i) Sum[i] += Sum[i - 1];
for (int i = n; i >= 1; --i) SA[Sum[VC[i]]--] = y[i];
t = x; x = y; y = t; p = 1;
x[SA[1]] = 1;
for (int i = 2; i <= n; ++i)
x[SA[i]] = Cmp(y, SA[i], SA[i - 1], j) ? p : ++p;
}
for (int i = 1; i <= n; ++i) Rank[SA[i]] = i; //GetHeight
int h = 0, o;
for (int i = 1; i <= n; ++i) {
if (Rank[i] == 1) continue;
o = SA[Rank[i] - 1];
while (A[i + h] == A[o + h]) ++h;
Height[Rank[i]] = h;
if (h > 0) --h;
}
} int main()
{
scanf("%s", S + 1);
n = strlen(S + 1);
for (int i = 1; i <= n; ++i) A[i] = S[i] - 'a' + 1;
DA(A, n, 26);
Ans = 0ll; Temp = 0ll;
for (int i = 1; i <= n; ++i)
Ans += (LL)(n - i + 1) * (LL)(n - 1);
Top = 0;
St[++Top] = n + 1;
for (int i = n; i >= 2; --i) {
while (Top > 0 && Height[St[Top]] > Height[i]) --Top;
int x = St[Top];
f[i] = (LL)Height[i] + (LL)Height[i] * (x - i - 1) + (LL)f[x];
Temp += f[i];
St[++Top] = i;
}
Ans -= Temp * 2ll;
printf("%lld\n", Ans);
return 0;
}

  

[BZOJ 3238] [AHOI 2013] 差异 【后缀数组 + 单调栈】的更多相关文章

  1. 【BZOJ-3238】差异 后缀数组 + 单调栈

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

  2. BZOJ.4199.[NOI2015]品酒大会(后缀数组 单调栈)

    BZOJ 洛谷 后缀自动机做法. 洛谷上SAM比SA慢...BZOJ SAM却能快近一倍... 显然只需要考虑极长的相同子串的贡献,然后求后缀和/后缀\(\max\)就可以了. 对于相同子串,我们能想 ...

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

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

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

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

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

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

  6. bzoj3238 [Ahoi2013]差异 后缀数组+单调栈

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

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

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

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

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

  9. 【BZOJ3879】SvT 后缀数组+单调栈

    [BZOJ3879]SvT Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个询问,我们给出若干 ...

随机推荐

  1. js判断input输入框为空时遇到的问题 弹窗后,光标没有定位到输入框,而是直接执行我的处理页面程序

    无论是会员注册还是提交订单,我们都要使用到form表单,此时我们在处理数据时,就要判断用户填写的信息.一次是直接通过js判断input输入框是否没有填信息,然后在后台处理文件中通过过滤字符串后再次判断 ...

  2. CMAKE 学习

    http://www.cnblogs.com/coderfenghc/archive/2012/06/16/CMake_ch_01.html

  3. spring mvc DispatcherServlet详解之一---处理请求深入解析(续)

    上文中,我们知道分发过程有以下步骤: 分发过程如下: 1. 判断是否设置了multipart resolver,设置的话转换为multipart request,没有的话则继续下面的步骤. 2. 根据 ...

  4. myeclipse配置svn亲测

    1.安装目录更改为myeclipse install 目录:E:\MyEclipse85\MyEclipse 8.5common 目录:           E:\MyEclipse85\Common ...

  5. 事件触发函数中的this,target,currentTarget,srcElement

    要解释其中的区别,首先要理解浏览器的事件机制, 现在主流的浏览器事件基本是先捕获再冒泡,IE浏览器只有冒泡阶段 事件是在冒泡阶段触发的 看看这个HTML 当我点击"我是父节点的时候" ...

  6. asp.net 的脚本

    asp.net的 Web 控件有时会包装一些用户端脚本 (client-side scripting),在控件被绘制时输出到用户端,这些脚本多数被包装在 DLL 的资源档中,并由 ScriptReso ...

  7. alpha属性设置

    alpha是来设置透明度的,它的基本属性是filter:alpha(opacity,finishopacity,style,startX,startY,finishX,finishY).opacity ...

  8. teamview centos 配置

    1.下载teamview centos版本,本人喜欢tar.gz版本,但是官网只有rpm版本,附件中即为官网下载的teamview11 官方下载地址:https://www.teamviewer.co ...

  9. HTML5表单提交和PHP环境搭建

    HTML5表单提交相关内容和PHP环境搭建需要的软件(只备注) (2)举例介绍 (3)PHP环境搭建

  10. JavaScript核心

    JavaScript核心 arguments对象 Array对象 Boolean对象 Date对象 Error对象 Function对象 Global对象 Math对象 Number对象 Object ...