【BZOJ3238】差异(后缀数组,单调栈)
题意:

思路:显然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】差异(后缀数组,单调栈)的更多相关文章
- 【BZOJ-3238】差异 后缀数组 + 单调栈
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1561 Solved: 734[Submit][Status] ...
- 【BZOJ3238】[Ahoi2013]差异 后缀数组+单调栈
[BZOJ3238][Ahoi2013]差异 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Ou ...
- BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2326 Solved: 1054[Submit][Status ...
- [AHOI2013] 差异 - 后缀数组,单调栈
[AHOI2013] 差异 Description 求 \(\sum {len(T_i) + len(T_j) - 2 lcp(T_i,T_j)}\) 的值 其中 \(T_i (i = 1,2,... ...
- bzoj3238 [Ahoi2013]差异 后缀数组+单调栈
[bzoj3238][Ahoi2013]差异 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Ou ...
- BZOJ3238 [Ahoi2013]差异 【后缀数组 + 单调栈】
题目链接 BZOJ3238 题解 简单题 经典后缀数组 + 单调栈套路,求所有后缀\(lcp\) #include<iostream> #include<cstdio> #in ...
- BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈
BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao ...
- 【BZOJ3879】SvT 后缀数组+单调栈
[BZOJ3879]SvT Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个询问,我们给出若干 ...
- BZOJ_3879_SvT_后缀数组+单调栈
BZOJ_3879_SvT_后缀数组+单调栈 Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个 ...
- BZOJ.4199.[NOI2015]品酒大会(后缀数组 单调栈)
BZOJ 洛谷 后缀自动机做法. 洛谷上SAM比SA慢...BZOJ SAM却能快近一倍... 显然只需要考虑极长的相同子串的贡献,然后求后缀和/后缀\(\max\)就可以了. 对于相同子串,我们能想 ...
随机推荐
- VUE学习之计算属性computed
计算属性:computed 先看一下官网的说法 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑会让模板过重且难以维护.例如: <div id="ex ...
- tp5增加验证的自定义规则
- IIS 相关配置
IIS 和 VS 安装顺序 正常情况是先装IIS,后装VS:这样就不会发生错误了,因为asp.net就可以注册写入到IIS中.如果先装VS,再装IIS,这样就会导致"访问IIS元数据库失败& ...
- 235 Lowest Common Ancestor of a Binary Search Tree 二叉搜索树的最近公共祖先
给定一棵二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 详见:https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-s ...
- Spring-security自定义配置器
定义配置器 public final class MyFilterConfigurer<H extends HttpSecurityBuilder<H>> extends Se ...
- 使用_CRTDBG_LEAK_CHECK_DF检查VC程序的内存泄漏(转)
我们知道,MFC程序如果检测到存在内存泄漏,退出程序的时候会在调试窗口提醒内存泄漏.例如: class CMyApp : public CWinApp{public:BOOL InitApplicat ...
- python 关于一个懒惰和非懒惰的
>>> pa = re.compile(r'<.*>') >>> result = pa.findall('<H1>title</H1 ...
- js文件中引用其他js文件
这一个功能的作用是做自己的js包时,可以通过引入一个整体的js文件而引入其他js. 只需要在总体的js加上这一句话 document.write("<script type='text ...
- HDU_3732_(多重背包)
Ahui Writes Word Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- JMeter怎样测试WebSocket,如何设置(一)
一.安装WebSocket取样器 1.从JMeter插件管理器官网下载:https://jmeter-plugins.org/ 把这6个jar包放到C:\JMeter\apache-jmeter-3. ...