Description

  先分析一下题目,我们显然可以直接算出sigma(len[Ti]+len[Tj])的值=(n-1)*n*(n+1)/2

  接着就要去算这个字符串中所有后缀的两两最长公共前缀总和

  首先可以想到后缀数组,我们计算好后缀数组之后再进行对height数组的计算

  对于以x,y开头的后缀,它们的最长公共前缀为min(height[sa[i]])(rank[x]<=i<=rank[y])

  但从以往习惯的height数组入手我们发现并没有办法解决这个问题

  不如换个角度思考,我们可以枚举这个最小的数!

  我们定义一个区间内最小的height为数值最小的情况下下标最小的位置

  那么一个数是最小的height,当且仅当这个区间的左边界到它的位置中没有数值小于等于它的数,它的右边界到它的位置中没有数值小于它的数

  我们可以用单调栈处理处这个左边界和右边界最远可以到达的位置

  然后乘法原理计算出答案就可以了

  代码写得很长的样子...(不知道为什么别人的SA好像写得都比我短...


 program bzoj3238;
const maxn=;
var s,a,rank,sa,tmp,height,l,r,st:array[-..maxn]of int64;
ans,n:int64;
ss:ansistring;
i:longint; function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end; function compare(x,y,p:longint):longint;
begin
while (x+p-<n)and(y+p-<n)and(a[x+p-]=a[y+p-]) do inc(p);
exit(p-);
end; procedure Suffix_Array;
var i,j,p,size,v0,v1,v00,v01:longint;
begin
if n> then size:=n else size:=;
for i:= to n- do rank[i]:=a[i];
for i:= to size- do s[i]:=;
for i:= to n- do inc(s[a[i]]);
for i:= to size- do inc(s[i],s[i-]);
for i:=n- downto do
begin
dec(s[a[i]]);
sa[s[a[i]]]:=i;
end;
j:=;
while j<=n do
begin
p:=;
for i:=n-j to n- do
begin
tmp[p]:=i;inc(p);
end;
for i:= to n- do if sa[i]-j>= then
begin
tmp[p]:=sa[i]-j;inc(p);
end;
for i:= to size- do s[i]:=;
for i:= to n- do inc(s[rank[i]]);
for i:= to size- do inc(s[i],s[i-]);
for i:=n- downto do
begin
dec(s[rank[tmp[i]]]);
sa[s[rank[tmp[i]]]]:=tmp[i];
end;
p:=;tmp[sa[]]:=;
for i:= to n- do
begin
v0:=sa[i-];v1:=sa[i];
if v0+j<n then v00:=rank[v0+j] else v00:=-;
if v1+j<n then v01:=rank[v1+j] else v01:=-;
if (rank[v0]=rank[v1])and(v00=v01) then tmp[sa[i]]:=p else
begin
inc(p);tmp[sa[i]]:=p;
end;
end;
for i:= to n- do rank[i]:=tmp[i];
j:=j << ;
end;
end; procedure Calc_Height;
var i:longint;
begin
if rank[]= then height[]:= else height[]:=compare(,sa[rank[]-],);
for i:= to n- do
if rank[i]= then height[i]:= else height[i]:=compare(i,sa[rank[i]-],max(height[i-],));
end; procedure Solve;
var i,top:longint;
begin
height[-]:=-maxlongint;
st[]:=-;sa[-]:=-;top:=;
for i:= to n- do
begin
while height[sa[st[top]]]>=height[sa[i]] do dec(top);
l[i]:=st[top];
inc(top);st[top]:=i;
end;
st[]:=n;sa[n]:=-;top:=;
for i:=n- downto do
begin
while height[sa[st[top]]]>height[sa[i]] do dec(top);
r[i]:=st[top];
inc(top);st[top]:=i;
end;
for i:= to n- do dec(ans,height[sa[i]]*(i-l[i])*(r[i]-i)*);
writeln(ans);
end; begin
readln(ss);
n:=length(ss);
for i:= to n do a[i-]:=ord(ss[i])-;
for i:= to n do inc(ans,i*(n-));
Suffix_Array;
Calc_Height;
Solve;
end.
 
 

[BZOJ3238][Ahoi2013]差异解题报告|后缀数组的更多相关文章

  1. P4248 [AHOI2013]差异 解题报告

    P4248 [AHOI2013]差异 题目描述 给定一个长度为 \(n\) 的字符串 \(S\),令 \(T_i\) 表示它从第 \(i\) 个字符开始的后缀.求 \[\displaystyle \s ...

  2. BZOJ 3238: [Ahoi2013]差异((单调栈+后缀数组)/(后缀树))

    [传送门[(https://www.lydsy.com/JudgeOnline/problem.php?id=3238) 解题思路 首先原式可以把\(len\)那部分直接算出来,然后通过后缀数组求\( ...

  3. [BZOJ2754] [SCOI2012]喵星球上的点名解题报告|后缀数组

    a180285幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣.   假设课堂上有N个喵星人,每个喵星人的名字由姓和名构成.喵星球上的老师会选择M个串来点名,每次读出一个串的 ...

  4. [BZOJ2946] [Poi2000]公共串解题报告|后缀数组

    给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 单词个数<=5,每个单词长度<=2000     尽管最近在学的是SAM...但是看到这个题还是忍不住想写SA... (其实是不 ...

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

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

  6. BZOJ3238 [Ahoi2013]差异 【SAM or SA】

    BZOJ3238 [Ahoi2013]差异 给定一个串,问其任意两个后缀的最长公共前缀长度的和 1.又是后缀,又是\(lcp\),很显然直接拿\(SA\)的\(height\)数组搞就好了,配合一下单 ...

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

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

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

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

  9. BZOJ3238: [Ahoi2013]差异(后缀数组)

    Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Output 54 解题思路: 看到lcp,想到了 ...

随机推荐

  1. 「暑期训练」「Brute Force」 Multiplication Table (CFR256D2D)

    题意 给定一矩阵M" role="presentation">MM,Mij=ij" role="presentation">Mi ...

  2. 「个人训练」Can you solve this equation?(HDU-2199)

    题意与分析 纯粹水题.本来想做下放松心情的,结果还是被坑了qaq 重点就是在浮点误差.比较左右的下次就直接上1e-10,别看着题目说1e-4然后给个-5,结果暴wa.气傻了..... 代码 #incl ...

  3. 做小Leader的心得体会

    只是自己的工作心得体会,代码属于也不够专业,大家不喜勿喷. 8月份来到这家新公司,没过一个月给派了个活:带着两个小弟给某银行开发一个小工具.功能很简单,就是用Java做一个windows上的C端工具, ...

  4. Jmeter非GUI命令参数说明

    查看帮助 -h, --help print usage information and exit 查看版本 -v, --version print the version information an ...

  5. virtualBox 安装 CentOs 6.8 以及网络配置

    安装 virtual box 基本设置: 1.创建虚拟电脑 类型:Linux 版本:Red Hat(64-bit) 这个64/32 和电脑具体配置关系. 然后就是路next or 设置常规的东西. 2 ...

  6. MySQL性能分析和优化-part 1

    MySQL性能优化 平时我们在使用MySQL的时候,怎么评估系统的运行状态,怎么快速定位系统瓶颈,又如何快速解决问题呢? 本文总结了多年来MySQL优化的经验,系统介绍MySQL优化的方法. OS性能 ...

  7. Understand:高效代码静态分析神器详解(一) | 墨香博客 http://www.codemx.cn/2016/04/30/Understand01/

    Understand:高效代码静态分析神器详解(一) | 墨香博客 http://www.codemx.cn/2016/04/30/Understand01/ ===== 之前用Windows系统,一 ...

  8. Linux SPI总线和设备驱动架构之二:SPI通用接口层

    通过上一篇文章的介绍,我们知道,SPI通用接口层用于把具体SPI设备的协议驱动和SPI控制器驱动联接在一起,通用接口层除了为协议驱动和控制器驱动提供一系列的标准接口API,同时还为这些接口API定义了 ...

  9. python学习笔记-list的用法

    1.list的定义 list = [] list = [1,2,'a','b'](list中的元素不一定是一个类型) 2.list的操作 1)list.append(value) 2)list.ins ...

  10. json.dumps错误:'utf8' codec can't decode byte解决方案

    一次在使用json.dumps()过程中,出现错误提示: ERROR:"UnicodeDecodeError: 'utf8' codec can't decode byte 0xe1 in ...