题意:

思路:显然len(t[i])+len(t[j])这部分的和是一定的

那么问题就在于如何快速求出两两之间lcp之和

考虑将它们排名后用SA可以很方便的求出lcp,且对答案没有影响,因为形式都是数对

所以用SA求出height

每个位置的height作为lcp的区间为扩展到最左最右,直到height[x]<height[i],height[y]<height[i]

这样合法的左区间为[x+1,i],右区间为[i,y-1]

考虑如何维护一个支持寻找最靠近当前位置的比当前位置上的数小的位置

这个可以用两次单调栈维护

但还要考虑到重复计算的情况,比如有多个最小值覆盖了全部区域

我们可以在比较时其中一次取等号,一次不取

 var x,y,sa,rank,height,wc,wd,a:array[..]of longint;
l,r:array[..]of int64;
stk:array[..]of longint;
n,i,m,top:longint;
ans,j:int64;
ch:ansistring; function min(x,y:longint):longint;
begin
if x<y then exit(x);
exit(y);
end; function cmp(a,b,l:longint):boolean;
begin
exit((y[a]=y[b])and(y[a+l]=y[b+l]));
end; procedure swap(var x,y:longint);
var t:longint;
begin
t:=x; x:=y; y:=t;
end; procedure getsa(n:longint);
var i,j,p:longint;
begin
for i:= to n- do
begin
x[i]:=a[i];
inc(wc[x[i]]);
end;
for i:= to m- do wc[i]:=wc[i-]+wc[i];
for i:=n- downto do
begin
dec(wc[x[i]]);
sa[wc[x[i]]]:=i;
end;
j:=; p:=;
while p<n do
begin
p:=;
for i:=n-j to n- do
begin
y[p]:=i; inc(p);
end;
for i:= to n- do
if sa[i]>=j then begin y[p]:=sa[i]-j; inc(p); end;
for i:= to n- do wd[i]:=x[y[i]];
for i:= to m- do wc[i]:=;
for i:= to n- do inc(wc[wd[i]]);
for i:= to m- do wc[i]:=wc[i-]+wc[i];
for i:=n- downto do
begin
dec(wc[wd[i]]);
sa[wc[wd[i]]]:=y[i];
end;
for i:= to n do swap(x[i],y[i]);
p:=; x[sa[]]:=;
for i:= to n- do
if cmp(sa[i-],sa[i],j) then x[sa[i]]:=p-
else begin x[sa[i]]:=p; inc(p); end;
j:=j<<;
m:=p;
end;
end; procedure getheight(n:longint);
var i,j,k:longint;
begin
k:=;
for i:= to n do rank[sa[i]]:=i;
for i:= to n- do
begin
if k> then dec(k);
j:=sa[rank[i]-];
while a[i+k]=a[j+k] do inc(k);
height[rank[i]]:=k;
end;
end; begin
assign(input,'bzoj3238.in'); reset(input);
assign(output,'bzoj3238.out'); rewrite(output);
readln(ch);
n:=length(ch);
for i:= to n- do a[i]:=ord(ch[i+])-ord('a')+;
a[n]:=; m:=;
getsa(n+);
getheight(n);
stk[]:=; height[]:=-maxlongint; top:=;
for i:= to n do
begin
while (top>)and(height[i]<height[stk[top]]) do dec(top);
if stk[top]= then l[i]:=
else l[i]:=stk[top]+;
inc(top); stk[top]:=i;
end; stk[]:=n+; height[n+]:=-maxlongint; top:=;
for i:=n downto do
begin
while (top>)and(height[i]<=height[stk[top]]) do dec(top);
if stk[top]=n+ then r[i]:=n
else r[i]:=stk[top]-;
inc(top); stk[top]:=i;
end; ans:=int64(n-)*int64(n)*(n+) div ;
for i:= to n do ans:=ans-*(-l[i]+i+)*(r[i]-i+)*height[i];
//for i:= to n+ do writeln(l[i],' ',r[i]);
writeln(ans);
close(input);
close(output);
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. 为什么Markdown能夺得程序员的青睐

    Markdown基本情况概述 Markdown是在HTML的基础上产生的.HTML的功能已经足够强大,可以编写出漂亮的网页.HTML在没有CSS的加持上,尽管不能显示出绚丽多彩的网页,但是仍然可以达到 ...

  2. 整理 Xamarin.Forms - Plugins

    Open Source Components for Xamarin Xamarin官方整理的一些开源组件,有需要可以先到这里找 GitHub: xamarin/XamarinComponents: ...

  3. 士兵杀敌 三 --- O( 1 ) 的时间复杂度 .

    一看就是 十分简单的  题  ,   然后上去开始无脑程序 超时~~~      感觉时间复杂度 , 已经很低了  ,  但是并没有什么卵用 . #include<stdio.h> #in ...

  4. Spring.Net学习笔记(7)-事务

    一.开发环境 操作系统:Win7 编译器:VS2010 二.涉及程序集 Spring.Core.dll Spring.Data.dll Common.Logging.dll 三.开发过程 1.项目结构 ...

  5. Java中PrintStream(打印输出流)

    Java中PrintStream(打印输出流)   PrintStream 是打印输出流,它继承于FilterOutputStream. PrintStream 是用来装饰其它输出流.它能为其他输出流 ...

  6. 【译】x86程序员手册27-7.6任务链

    7.6 Task Linking 任务链 The back-link field of the TSS and the NT (nested task) bit of the flag word to ...

  7. dubbo之日志适配及访问日志

    日志适配 自 2.2.1 开始,dubbo 开始内置 log4j.slf4j.jcl.jdk 这些日志框架的适配 1,也可以通过以下方式显示配置日志输出策略: 命令行 java -Ddubbo.app ...

  8. 外观模式(Facade)-子系统的协作与整合-接口模式

    对子系统进行整合,对外提供更强大或更便捷的接口. 在一个模块和几个子系统进行通信时考虑. 什么是外观模式? 外观模式(Facade),为子系统中的一组接口提供一个一致的界面,定义一个高层接口,这个接口 ...

  9. 系统异常 NSException.h

    FOUNDATION_EXPORT NSExceptionName const NSGenericException; FOUNDATION_EXPORT NSExceptionName const ...

  10. 前端零基础快速入门JavaScript

    JavaScript代码可以直接嵌在网页的任何地方,不过通常我们都把JavaScript代码放到<head>中: <html><head> <script&g ...