这道是求长度不小于 k 的公共子串的个数...很不幸,我又TLE了...

解法参考论文以及下面的链接

http://www.cnblogs.com/vongang/archive/2012/11/20/2778481.html

http://hi.baidu.com/fpkelejggfbfimd/item/5c76cfcba28fba26e90f2ea6

 const maxn=;
var
c,h,rank,sa,x,y,stack:array[..maxn] of longint;
n,k,top:longint;
a,b,d:int64;
s1,s2:ansistring; function max(x,y:longint):longint; begin if x>y then exit(x) else exit(y); end;
function min(x,y:longint):longint; begin if x<y then exit(x) else exit(y); end; procedure make;
var p,i,tot:longint;
begin
p:=;
while p<n do
begin
fillchar(c,sizeof(c),);
for i:= to n-p do y[i]:=rank[i+p];
for i:= n-p+ to n do y[i]:=;
for i:= to n do inc(c[y[i]]);
for i:= to n do inc(c[i],c[i-]);
for i:= to n do
begin
sa[c[y[i]]]:=i;
dec(c[y[i]]);
end;
fillchar(c,sizeof(c),);
for i:= to n do x[i]:=rank[i];
for i:= to n do inc(c[x[i]]);
for i:= to n do inc(c[i],c[i-]);
for i:= n downto do
begin
y[sa[i]]:=c[x[sa[i]]];
dec(c[x[sa[i]]]);
end;
for i:= to n do sa[y[i]]:=i;
tot:=;
rank[sa[]]:=;
for i:= to n do
begin
if (x[sa[i]]<>x[sa[i-]]) or (x[sa[i]+p]<>x[sa[i-]+p]) then inc(tot);
rank[sa[i]]:=tot;
end;
p:=p<<;
end;
for i:= to n do sa[rank[i]]:=i;
end; procedure makeh(s:ansistring);
var i,j,p:longint;
begin
h[]:=; p:=;
for i:= to n do
begin
p:=max(p-,);
if rank[i]= then continue;
j:=sa[rank[i]-];
while (i+p<=n) and (j+p<=n) and (s[i+p]=s[j+p]) do inc(p);
h[rank[i]]:=p;
end;
end; procedure init(s:ansistring);
var i,tot:longint;
ch:char;
begin
n:=length(s);
for i:= to n do c[i]:=;
for i:= to n do x[i]:=ord(s[i]);
for i:= to n do inc(c[x[i]]);
for i:= to do inc(c[i],c[i-]);
for i:= to n do
begin
sa[c[x[i]]]:=i;
dec(c[x[i]]);
end;
rank[sa[]]:=;
tot:=;
for i:= to n do
begin
if x[sa[i]]<>x[sa[i-]] then inc(tot);
rank[sa[i]]:=tot;
end;
fillchar(x,sizeof(x),);
fillchar(y,sizeof(y),);
make;
makeh(s);
end; function calc(s:ansistring):int64;
var ctb,i,m,ht,top:longint;
ans:int64;
begin
ans:=;
init(s);
h[]:=k-; h[n+]:=k-;
top:=; i:=;
stack[]:=;
while i<=n+ do
begin
ht:=h[stack[top]];
if ((h[i]<k) and (top=)) or (h[i]=ht) then inc(i)
else if h[i]>ht then begin inc(top);stack[top]:=i; inc(i); end
else
begin
m:=i-stack[top]+;
if (h[i]>=k) and (h[i]>h[stack[top-]]) then
begin
ctb:=ht-h[i];
h[stack[top]]:=h[i];
end
else
begin
ctb:=ht-h[stack[top-]];
dec(top);
end;
inc(ans,(int64(m)*int64(m-) div ) *int64(ctb));
end
end;
exit(ans);
end; Begin
readln(k);
while k<> do
begin
readln(s1);
a:=calc(s1);
readln(s2);
b:=calc(s2);
s1:=s1+'$'+s2;
d:=calc(s1);
writeln(d-a-b);
readln(k);
end;
End.

【POJ3415】 Common Substrings (SA+单调栈)的更多相关文章

  1. POJ3415 Common Substrings —— 后缀数组 + 单调栈 公共子串个数

    题目链接:https://vjudge.net/problem/POJ-3415 Common Substrings Time Limit: 5000MS   Memory Limit: 65536K ...

  2. Codeforces 802I Fake News (hard) (SA+单调栈) 或 SAM

    原文链接http://www.cnblogs.com/zhouzhendong/p/9026184.html 题目传送门 - Codeforces 802I 题意 求一个串中,所有本质不同子串的出现次 ...

  3. poj3415 Common Substrings(后缀数组,单调栈 | 后缀自动机)

    [题目链接] http://poj.org/problem?id=3415 [题意] A与B长度至少为k的公共子串个数. [思路] 基本思想是将AB各个后缀的lcp-k+1的值求和.首先将两个字符串拼 ...

  4. POJ3415 Common Substrings 【后缀数组 + 单调栈】

    常见的子串 时间限制: 5000MS   内存限制: 65536K 提交总数: 11942   接受: 4051 描述 字符串T的子字符串被定义为: Ť(我,ķ)= Ť 我 Ť 我 1 ... Ť I ...

  5. poj 3415 Common Substrings【SA+单调栈】

    把两个串中间加一个未出现字符接起来,然后求SA 然后把贡献统计分为两部分,在排序后的后缀里,属于串2的后缀和排在他前面属于串1的后缀的贡献和属于串1的后缀和排在他前面属于串2的后缀的贡献 两部分分别作 ...

  6. Codeforces 873F Forbidden Indices 字符串 SAM/(SA+单调栈)

    原文链接https://www.cnblogs.com/zhouzhendong/p/9256033.html 题目传送门 - CF873F 题意 给定长度为 $n$ 的字符串 $s$,以及给定这个字 ...

  7. luogu2178/bzoj4199 品酒大会 (SA+单调栈)

    他要求的就是lcp(x,y)>=i的(x,y)的个数和a[x]*a[y]的最大值 做一下后缀和,就只要求lcp=i的了 既然lcp(x,y)=min(h[rank[x]+1],..,[h[ran ...

  8. Codeforces 1073G Yet Another LCP Problem $SA$+单调栈

    题意 给出一个字符串\(s\)和\(q\)个询问. 每次询问给出两个长度分别为\(k,l\)的序列\(a\)和序列\(b\). 求\(\sum_{i=1}^{k}\sum_{j=1}^{l}lcp(s ...

  9. BZOJ3238 [Ahoi2013]差异 SA+单调栈

    题面 戳这里 题解 考虑把要求的那个东西拆开算,前面一个东西像想怎么算怎么算,后面那个东西在建出\(height\)数组后相当于是求所有区间\(min\)的和*2,单调栈维护一波即可. #includ ...

随机推荐

  1. 给大家一个我的QQ群

    很少关注博客了,提供一个QQ群讨论 我的一个QQ群:158351344

  2. SHGetSpecialFolderLocation获取开始文件夹

    SHGetSpecialFolderLocation函数可以获取windows 特殊目录 函数原型:(MSDN官方链接:https://msdn.microsoft.com/en-us/library ...

  3. Java OOP——JAVA关键字与保留字说明及使用

    1.abstract abstract 关键字可以修改类或方法. abstract 类可以扩展(增加子类),但不能直接实例化. abstract 方法不在声明它的类中实现,但必须在某个子类中重写. - ...

  4. python--pexpect

    大家好,最近工作比较忙,所以没时间来更新博客.趁着还没在下个版本来临之前,来这边再更新更新.是之前学习到的一些老知识点,就当来巩固一下了.开心QAQ 今天给大家介绍的是--Pexpect Expect ...

  5. Pandas 数据结构Dataframe:基本概念及创建

    "二维数组"Dataframe:是一个表格型的数据结构,包含一组有序的列,其列的值类型可以是数值.字符串.布尔值等. Dataframe中的数据以一个或多个二维块存放,不是列表.字 ...

  6. 19,Ubuntu安装之python开发

      什么??公司要用Ubuntu(乌班图)?不会用??怎么进行python开发??? 乌班图操作系统下载地址:http://releases.ubuntu.com/18.04/ubuntu-18.04 ...

  7. mybatis和redis整合 log4j打印sql语句

    首先,需要在项目中引进jedis-2.8.1.jar包,在pom.xml里加上 <dependency> <groupId>redis.clients</groupId& ...

  8. centos使用--supervisor使用

    目录 1 下载程序并安装 2 编辑配置文件 3 supervisor的使用 4 配置文件详细解析 参考资料 supervisor是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变 ...

  9. 通过重写ViewGroup学习onMeasure()和onLayout()方法

    在继承ViewGroup类时,需要重写两个方法,分别是onMeasure和onLayout. 1,在方法onMeasure中调用setMeasuredDimension方法 void android. ...

  10. python练习1 ——菱形打印

    具体请看链接: 链接 2018-09-29 12:51:45