【SPOJ220】Relevant Phrases of Annihilation (SA)
成功完成3连T! 嗯没错,三道TLE简直爽到不行,于是滚去看是不是模版出问题了..拿了3份其他P党的模版扔上去,嗯继续TLE...蒟蒻表示无能为力了...
思路像论文里面说的,依旧二分长度然后分组...然后记录下每个字符的最大和最小值去判断是否满足全部成立...完事...写起来其实蛮简单的...
const maxn=;
var
h,sum,rank,x,y,sa,c,lx,rx,col:array[..maxn] of longint;
n,k,maxlen,t,q:longint;
s: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 swap(var x,y:longint); var tmp:longint; begin tmp:=x;x:=y;y:=tmp; end; procedure make;
var p,i,j,tot:longint;
begin
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;
if tot=n then break;
p:=p<<;
end;
for i:= to n do sa[rank[i]]:=i;
h[]:=; p:=;
for i:= to n do
begin
p:=max(p-,);
if rank[i]= then continue;
j:=sa[rank[i]-];
while (j+p<=n) and (i+p<=n) and (s[i+p]=s[j+p]) do inc(p);
h[rank[i]]:=p;
end;
end; procedure init;
var i,j,tot,p,m:longint;
s1:ansistring;
begin
readln(k);
readln(s);
for i:= to length(s) do col[i]:=;
maxlen:=length(s);
for i:= to k do
begin
readln(s1);
maxlen:=max(length(s1),maxlen);
s:=s+'#';
for j:= length(s)+ to length(s)+length(s1) do col[j]:=i;
s:=s+s1;
end;
n:=length(s);
fillchar(c,sizeof(c),);
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;
tot:=;
rank[sa[]]:=;
for i:= to n do
begin
if x[sa[i]]<>x[sa[i-]] then inc(tot);
rank[sa[i]]:=tot;
end;
make;
end; function check(len:longint):boolean;
var i,j,t,cnt:longint;
begin
for i:= to n do
begin
if h[i]<len then
begin
fillchar(lx,sizeof(lx),$7f);
fillchar(rx,sizeof(rx),);
lx[col[sa[i]]]:=sa[i];
rx[col[sa[i]]]:=sa[i];
end
else
begin
t:=col[sa[i]];
lx[t]:=min(lx[t],sa[i]);
rx[t]:=max(rx[t],sa[i]);
cnt:=;
for j:= to k do if rx[j]-lx[j]+>=len then inc(cnt);
if cnt=k then exit(true);
end;
end;
exit(false);
end; procedure solve;
var l,r,mid,ans:longint;
begin
l:=; r:=maxlen; ans:=;
while l<=r do
begin
mid:=(l+r)>>;
if check(mid) then
begin
ans:=mid;
l:=mid+;
end
else r:=mid-;
end;
writeln(ans);
end; Begin
readln(t);
for q:= to t do
begin
init;
solve;
end;
End.
【SPOJ220】Relevant Phrases of Annihilation (SA)的更多相关文章
- 【SPOJ220】Relevant Phrases of Annihilation(后缀数组,二分)
题意: n<=10,len<=1e4 思路: #include<cstdio> #include<cstring> #include<string> # ...
- 【SPOJ 220】Relevant Phrases of Annihilation
http://www.spoj.com/problems/PHRASES/ 求出后缀数组然后二分. 因为有多组数据,所以倍增求后缀数组时要特判是否越界. 二分答案时的判断要注意优化! 时间复杂度\(O ...
- SPOJ - PHRASES K - Relevant Phrases of Annihilation
K - Relevant Phrases of Annihilation 题目大意:给你 n 个串,问你最长的在每个字符串中出现两次且不重叠的子串的长度. 思路:二分长度,然后将height分块,看是 ...
- SPOJ - PHRASES Relevant Phrases of Annihilation —— 后缀数组 出现于所有字符串中两次且不重叠的最长公共子串
题目链接:https://vjudge.net/problem/SPOJ-PHRASES PHRASES - Relevant Phrases of Annihilation no tags You ...
- POJ - 3294~Relevant Phrases of Annihilation SPOJ - PHRASES~Substrings POJ - 1226~POJ - 3450 ~ POJ - 3080 (后缀数组求解多个串的公共字串问题)
多个字符串的相关问题 这类问题的一个常用做法是,先将所有的字符串连接起来, 然后求后缀数组 和 height 数组,再利用 height 数组进行求解. 这中间可能需要二分答案. POJ - 3294 ...
- 【SPOJ 220】 PHRASES - Relevant Phrases of Annihilation
[链接]h在这里写链接 [题意] 给你n(n<=10)个字符串. 每个字符串长度最大为1e4; 问你能不能找到一个子串. 使得这个子串,在每个字符串里面都不想交出 ...
- SPOJ 220 Relevant Phrases of Annihilation(后缀数组+二分答案)
[题目链接] http://www.spoj.pl/problems/PHRASES/ [题目大意] 求在每个字符串中出现至少两次的最长的子串 [题解] 注意到这么几个关键点:最长,至少两次,每个字符 ...
- 【string】KMP, 扩展KMP,trie,SA,ACAM,SAM,最小表示法
[KMP] 学习KMP,我们先要知道KMP是干什么的. KMP?KMPLAYER?看**? 正如AC自动机,KMP为什么要叫KMP是因为它是由三个人共同研究得到的- .- 啊跑题了. KMP就是给出一 ...
- SPOJ220 Relevant Phrases of Annihilation
http://www.spoj.com/problems/PHRASES/ 题意:给n个串,求n个串里面都有2个不重叠的最长的字串长度. 思路:二分答案,然后就可以嘿嘿嘿 PS:辣鸡题目毁我青春,一开 ...
随机推荐
- LeetCode426.Convert Binary Search Tree to Sorted Doubly Linked List
题目 Convert a BST to a sorted circular doubly-linked list in-place. Think of the left and right point ...
- ssm整合-错误2
1 警告: No mapping found for HTTP request with URI [/management] in DispatcherServlet with name 'dispa ...
- linux安装openldap步骤
目录 虚拟机环境:centos 7 一.环境准备 1.关闭 selinux firewalld 临时: setenforce 0 永久: vi /etc/sysconfig/selinux SELI ...
- HTML+CSS : 笔记整理(3 移动端布局简单了解)
流体布局:宽度用百分比,计算真实宽度用函数 : width: calc(25% - 4px); box-sizing: 1.content-box:默认计算方式 ,宽度和高度分别应用到元素的内容框.在 ...
- iOS-重构微博cell模型
一.Frame模型: -------------------WeiboFrame.h-------------------------------------------------- ------- ...
- 笔记-爬虫-模拟登录github
笔记-模拟登录github 1. 模拟登录github 1.1. 环境准备 安装/升级requests 2.20.0 pip install --upgrade requests pi ...
- 调用startActivityForResult后直接调用onActivityResult
人员都知道,可以经由过程应用 startActivityForResult() 和 onActivityResult() 办法来传递或接管参数. 然而在"轻听"项目中,还没比及被调 ...
- windows系统如何查看某个端口被谁占用
1.开始---->运行---->cmd,或者是window+R组合键,调出命令窗口 2.输入命令:netstat -ano,列出所有端口的情况.在列表中我们观察被占用的端口,比如是135, ...
- 【HTML&CSS】 第一章:DTD文档声明
<!DOCTYPE> 声明必须是 HTML 文档的第一行,位于 <html> 标签之前. <!DOCTYPE> 声明不是 HTML 标签:它是指示 web 浏览器关 ...
- 【Spiral Matrix】cpp
题目: Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spira ...