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

Description

Input

一行,一个字符串S

Output

一行,一个整数,表示所求值

Sample Input

cacao

Sample Output

54


前面那个len的和=(n-1)*n*(n+1)/2。只需要考虑后面的贡献。

求出height数组,然后问题转化为求所有区间的最小值之和。

设f[i]为所有右端点为i的区间的最小值之和。

每次找到i左边第一个height小于等于i的位置j,显然左端点在j之前那部分的答案之和为f[j],左端点在j之后的那部分的最小值为height[i]。

有f[i]=f[j]+(i-j)*height[i]。

维护一个单调栈(单调递增),每次找j就很方便。

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stdlib.h>
using namespace std;
#define N 500050
typedef long long ll;
int wa[N],wb[N],wv[N],ws[N],r[N],sa[N],height[N],rank[N],n,m,S[N],top;
ll f[N];
char s[N];
void build_suffix_array() {
m=129;
int i,j,p,*x=wa,*y=wb,*t;
for(i=0;i<m;i++) ws[i]=0;
for(i=0;i<n;i++) ws[x[i]=r[i]]++;
for(i=1;i<m;i++) ws[i]+=ws[i-1];
for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i;
for(j=p=1;p<n;j<<=1,m=p) {
for(p=0,i=n-j;i<n;i++) y[p++]=i;
for(i=0;i<n;i++) if(sa[i]-j>=0) y[p++]=sa[i]-j;
for(i=0;i<n;i++) wv[i]=x[y[i]];
for(i=0;i<m;i++) ws[i]=0;
for(i=0;i<n;i++) ws[wv[i]]++;
for(i=1;i<m;i++) ws[i]+=ws[i-1];
for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i];
for(t=x,x=y,y=t,x[sa[0]]=0,i=p=1;i<n;i++) {
if(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+j]==y[sa[i-1]+j]) x[sa[i]]=p-1;
else x[sa[i]]=p++;
}
}
for(i=1;i<n;i++) rank[sa[i]]=i;
for(i=p=0;i<n-1;height[rank[i++]]=p)
for(p?p--:0,j=sa[rank[i]-1];r[i+p]==r[j+p];p++); }
int main() {
scanf("%s",s);
n=strlen(s);
int i;
ll sum=1ll*n*(n+1)*(n-1)/2;
for(i=0;i<n;i++) r[i]=s[i];
r[n++]=0;
build_suffix_array();
for(i=0;i<n;i++) {
while(top&&height[i]<height[S[top]]) top--;
int j=S[top];
f[i]=f[j]+1ll*(i-j)*height[i]; sum-=2*f[i];
S[++top]=i;
}
printf("%lld\n",sum);
}

BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈的更多相关文章

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

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

  2. BZOJ_3238_[Ahoi2013]差异_后缀自动机

    BZOJ_3238_[Ahoi2013]差异_后缀自动机 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sam ...

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

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

  4. [BZOJ 3238] [AHOI 2013] 差异 【后缀数组 + 单调栈】

    题目链接:BZOJ - 3238 题目分析 显然,这道题就是求任意两个后缀之间的LCP的和,这与后缀数组的联系十分明显. 求出后缀数组后,求出字典序相邻两个后缀的LCP,即 Height 数组. 那么 ...

  5. [bzoj3238]差异(后缀数组+单调栈)

    显然我们可以先把len(Ti)+len(Tj)的值先算出来,再把LCP减去.所有len(Ti)+len(Tj)的值为n*(n-1)*(n+1)/2,这个随便在纸上画一画就可以算出来的. 接下来问题就是 ...

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

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

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

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

  8. BZOJ_3879_SvT_后缀数组+单调栈

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

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

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

随机推荐

  1. pywinauto处理UI自动化

    之前一个项目的特殊性, 以及一些操作权限上的问题,不能使用现有工具进行UI自动化. 在一些资深tester建议下决定采用Python的pywinauto模块来处理Windows控件的UI操作. 1. ...

  2. django-debug-toolbar的配置以及使用

    django-debug-toolbar django,web开中,用django-debug-toolbar来调试请求的接口,无疑是完美至极.   可能本人,见识博浅,才说完美至极, 大神,表喷,抱 ...

  3. 掌握 Java 泛型类型(一)

    为理解泛型类型为何如此有用,我们要将注意力转向 Java 语言中最容易引发错误的因素之一 - 需要不断地将表达式向下类型转换(downcast)为比其静态类型更为具体的数据类型(请参阅参考资料中的&q ...

  4. node.js代理设置

    1.设置代理 npm config set proxy=http://proxy.tencent.com:8080 设置代理服务器,比如:npm config set proxy=http://127 ...

  5. DDGScreenShot —图片加各种滤镜高逼格操作

    写在前面 图片加各种滤镜操作,当然苹果给开发者提供了相关的api和封装, 大部分开发者感觉这是这是晦涩难懂的,接下来就让我们来了解一下, 其实也没有那么深不可测. 代码如下(每一步已经解释的很详细) ...

  6. Linux安装mysql(Redhat6.5+MySQL5.7)(转载+原创补漏)

    一.下载 这里我创建了一目录software用于存放我们待会要下载的mysql包,先去到该目录 命令:cd /software命令:wget http://mirrors.sohu.com/mysql ...

  7. 为什么在JDBC要使用Class.forName();这句话

    为什么在调用JDBC的时候,我们总要写这句话:Class.forName("驱动类");解释:在JDBC编程中一般有以下几个步骤:1>加载驱动,也就是Class.forNam ...

  8. jieba库词频统计练习

    在sypder上运行jieba库的代码: import matplotlib.pyplot as pltfracs = [2,2,1,1,1]labels = 'houqin', 'jiemian', ...

  9. 团队项目第二阶段个人进展——Day3

    一.昨天工作总结 冲刺第三天,基本完成发布页面的布局 二.遇到的问题 添加照片的样式会随照片增加而改变 三.今日工作规划 分析要封装的数据有哪些,数据如何传到后端服务器中

  10. TensorFlow-谷歌深度学习库 命令行参数

    程序的入口: tf.app.run tf.app.run( main=None, argv=None ) 运行程序,可以提供'main'函数以及函数参数列表.处理flag解析然后执行main函数. 什 ...