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

接下来问题就是如何把LCP减去。我们先用后缀数组把height求出来,当有一段区间l~r,height[i]为height[l]~height[r]中的最小值,那么随便取rk[l]~rk[r]中的两个后缀,他们的LCP则都是height[i],这个很好理解吧。那么l~r这个区间里有(l-i+1)*(r-i+1)对后缀,所以我们最后的答案就要减去2*height[i]*(l-i+1)*(r-i+1)【1≤i≤n】。

然后就是如何求出每一个i的l~r了,暴力枚举+RMQ显然不行,那我们就用一个单调栈,栈里存着i前面height值比height[i]小的height值的编号,记为j,如果height[j]比height[i]大那么就弹出,那么这段区间的左端点则为栈顶的j+1,右端点同理。这样我们就可以求出每个height的l和r了。

奇丑无比的代码如下:

var
s:ansistring;
i:longint;
n,m,l,r,ans,top:int64;
rk,trk,sa,tsa,sum,h,ll,rr,st:array[..]of int64; procedure suffix;
var
i,j,p:longint;
begin
for i:= to n do begin trk[i]:=ord(s[i]);inc(sum[trk[i]]);end;
for i:= to do inc(sum[i],sum[i-]);
for i:=n downto do begin sa[sum[trk[i]]]:=i;dec(sum[trk[i]]);end;
rk[sa[]]:=;p:=;
for i:= to n do begin if trk[sa[i]]<>trk[sa[i-]] then inc(p);rk[sa[i]]:=p;end;
m:=p;j:=;
while m<n do
begin
move(rk,trk,sizeof(rk));fillchar(sum,sizeof(sum),);p:=;
for i:=n-j+ to n do begin inc(p);tsa[p]:=i;end;
for i:= to n do if sa[i]>j then begin inc(p);tsa[p]:=sa[i]-j;end;
for i:= to n do begin rk[i]:=trk[tsa[i]];inc(sum[rk[i]]);end;
for i:= to n do inc(sum[i],sum[i-]);
for i:=n downto do begin sa[sum[rk[i]]]:=tsa[i];dec(sum[rk[i]]);end;
rk[sa[]]:=;p:=;
for i:= to n do
begin
if (trk[sa[i]]<>trk[sa[i-]])or(trk[sa[i]+j]<>trk[sa[i-]+j])then inc(p);
rk[sa[i]]:=p;
end;
m:=p;j:=j*;
end;
h[]:=;p:=;
for i:= to n do
begin
if rk[i]= then continue;
j:=sa[rk[i]-];
while s[i+p]=s[j+p] do inc(p);
h[rk[i]]:=p;
if p> then dec(p);
end;
end; begin
readln(s);
n:=length(s);
s:=s+' ';
suffix;
ans:=n*(n-)*(n+)div ;
h[]:=-maxlongint;
for i:= to n do
begin
while h[i]<=h[st[top]] do dec(top);
if st[top]= then ll[i]:=
else ll[i]:=st[top]+;
inc(top);
st[top]:=i;
end;
h[n+]:=-maxlongint;top:=;st[]:=n+;
for i:=n downto do
begin
while h[i]<h[st[top]] do dec(top);
if st[top]=n+ then rr[i]:=n
else rr[i]:=st[top]-;
inc(top);
st[top]:=i;
end;
for i:= to n do
ans:=ans-*(i-ll[i]+)*(rr[i]-i+)*h[i];
writeln(ans);
end.

[bzoj3238]差异(后缀数组+单调栈)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. BZOJ_3879_SvT_后缀数组+单调栈

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

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

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

随机推荐

  1. Python小白学习之函数装饰器

    装饰器 2018-10-25 13:49:37 装饰器从字面意思就是用来装饰的,在函数可以理解为:在函数中,我们不想影响原来的函数功能,又想给函数添加新的功能,这时候我们就用到了装饰器. 一般函数操作 ...

  2. Jmeter性能测试使用记录

    使用背景 由于最近公司要求对一批接口做性能测试,所以重拾了一些对于Jmeter的使用,现将部分过程做记录,以便以后回溯. 接口参数化 数据参数文件使用了excel保存出的csv文件,dat格式的文件也 ...

  3. Spring学习(3):IOC基础(转载)

    一. IoC是什么 Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象 ...

  4. IO模型浅析-阻塞、非阻塞、IO复用、信号驱动、异步IO、同步IO

    最近看到OVS用户态的代码,在接收内核态信息的时候,使用了Epoll多路复用机制,对其十分不解,于是从网上找了一些资料,学习了一下<UNIX网络变成卷1:套接字联网API>这本书对应的章节 ...

  5. Linux内核学习笔记(5)-- 进程调度概述

    进程调度程序是多任务操作系统的基础,它是确保进程能有效工作的一个内核子系统,负责决定哪个进程投入运行.何时运行以及运行多长时间.只有通过进程调度程序的合理调度,系统资源才能够最大限度地发挥作用,多进程 ...

  6. LeetCode-124.二叉树中的最大路径和

    给定一个非空二叉树,返回其最大路径和. 本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列.该路径至少包含一个节点,且不一定经过根节点. 示例 1: 输入: [1,2,3] 1 / \ 2 ...

  7. Python基础灬函数(定义,参数)

    函数 函数定义 # 定义一个计算绝对值的函数 def cal_abs(x): if x >= 0: return x else: return -x # 调用函数 print('-1的绝对值是: ...

  8. Python基础知识-05-数据类型总结字典

    python其他知识目录 1.一道题,选择商品的序号.程序员和用户各自面对的序号起始值 如有变量 googs = ['汽车','飞机','火箭'] 提示用户可供选择的商品: 0,汽车1,飞机2,火箭用 ...

  9. 扩展Lucas定理 扩展Lucas板子

    题意概述:多组询问,给出N,K,M,要求回答C(N,K)%M,1<=N<=10^18,1<=K<=N,2<=M<=10^6 分析: 模数不为质数只能用扩展Lucas ...

  10. 到底什么是BFC、IFC、GFC和FFC,次奥?

    软件开发的一般被称为民工,搞前端的,有人形容为是掏粪工,说白了连民工级别高都没有.说直接点就是个制作界面的,注意,连设计界面的都算不上,一般前端都是拿着设计稿去照这样子开发的. 说这些无非是觉得前端前 ...