【POJ2774】Long Long Message (SA)

最长公共子串...两个字符串连在一起,中间放一个特殊字符隔开。求出height之后,枚举height,看两个后缀是不是分布于两段字符串..如果是,这个值就可以作为答案。取最大值即可。

  1 const maxn=200419;
  2 var
  3  c,h,rank,sa,x,y:array[0..maxn] of longint;
  4  n,k:longint;
  5  s:ansistring;
  6
  7 function max(x,y:longint):longint; begin if x>y then exit(x) else exit(y); end;
  8 function min(x,y:longint):longint; begin if x<y then exit(x) else exit(y); end;
  9 procedure swap(var x,y:longint); var tmp:longint; begin tmp:=x;x:=y;y:=tmp; end;
 10
 11 procedure make;
 12 var p,i,tot:longint;
 13 begin
 14  p:=1;
 15  while p<n do
 16   begin
 17    fillchar(c,sizeof(c),0);
 18    for i:= 1 to n-p do y[i]:=rank[i+p];
 19    for i:= n-p+1 to n do y[i]:=0;
 20    for i:= 1 to n do inc(c[y[i]]);
 21    for i:= 1 to n do inc(c[i],c[i-1]);
 22    for i:= 1 to n do
 23     begin
 24      sa[c[y[i]]]:=i;
 25      dec(c[y[i]]);
 26     end;
 27    fillchar(c,sizeof(c),0);
 28    for i:= 1 to n do x[i]:=rank[i];
 29    for i:= 1 to n do inc(c[x[i]]);
 30    for i:= 1 to n do inc(c[i],c[i-1]);
 31    for i:= n downto 1 do
 32     begin
 33      y[sa[i]]:=c[x[sa[i]]];
 34      dec(c[x[sa[i]]]);
 35     end;
 36    for i:= 1 to n do sa[y[i]]:=i;
 37    tot:=1;
 38    rank[sa[1]]:=1;
 39    for i:= 2 to n do
 40     begin
 41      if (x[sa[i]]<>x[sa[i-1]]) or (x[sa[i]+p]<>x[sa[i-1]+p]) then inc(tot);
 42      rank[sa[i]]:=tot;
 43     end;
 44    p:=p<<1;
 45   end;
 46  for i:= 1 to n do sa[rank[i]]:=i;
 47 end;
 48
 49 procedure makeh;
 50 var i,j,p:longint;
 51 begin
 52  h[1]:=0; p:=0;
 53  for i:= 1 to n do
 54   begin
 55    p:=max(p-1,0);
 56    if rank[i]=1 then continue;
 57    j:=sa[rank[i]-1];
 58    while (i+p<=n) and (j+p<=n) and (s[i+p]=s[j+p]) do inc(p);
 59    h[rank[i]]:=p;
 60   end;
 61 end;
 62
 63 procedure init;
 64 var i,tot:longint;
 65  s1:ansistring;
 66 begin
 67  readln(s);
 68  s:=s+‘#‘;
 69  k:=length(s);
 70  readln(s1);
 71  s:=s+s1;
 72  fillchar(c,sizeof(c),0);
 73  n:=length(s);
 74  for i:= 1 to n do x[i]:=ord(s[i]);
 75  for i:= 1 to n do inc(c[x[i]]);
 76  for i:= 1 to 128 do inc(c[i],c[i-1]);
 77  for i:= 1 to n do
 78   begin
 79    sa[c[x[i]]]:=i;
 80    dec(c[x[i]]);
 81   end;
 82  rank[sa[1]]:=1;
 83  tot:=1;
 84  for i:= 2 to n do
 85   begin
 86    if x[sa[i]]<>x[sa[i-1]] then inc(tot);
 87    rank[sa[i]]:=tot;
 88   end;
 89  make;
 90  makeh;
 91 end;
 92
 93 function range(x,y:longint):boolean;
 94 begin
 95  if (x<k) and (y>k) then exit(true);
 96  if (x>k) and (y<k) then exit(true);
 97  exit(false);
 98 end;
 99
100 procedure solve;
101 var ans,i:longint;
102 begin
103  ans:=0;
104  for i:= 2 to n do if range(sa[i],sa[i-1]) then ans:=max(h[i],ans);
105  writeln(ans);
106 end;
107
108 Begin
109  init;
110  solve;
111 End.
时间: 2024-11-06 09:34:03

【POJ2774】Long Long Message (SA)的相关文章

【POJ2774】Long Long Message(后缀数组)

[POJ2774]Long Long Message(后缀数组) 题面 Vjudge Description Little cat在Byterland的首都读物理专业.这些天他收到了一条悲伤地信息:他的母亲生病了.担心买火车票花钱太多(Byterland是一个巨大的国家,因此他坐火车回家需要16小时),他决定只给母亲发短信. Little cat的家境并不富裕,因此他经常去营业厅查看自己发短信花了多少钱.昨天营业厅的电脑坏掉了,打印出两条很长的信息.机智的little cat很快发现: 1.信息

【poj2774】 Long Long Message

[http://poj.org/problem?id=2774] (题目链接) 第一次用后缀数组,感觉有点神...才发现原来sa[0]是没用的.. 题意:给出两个只包含小写字母的字符串,求出最长连续公共子串. solution  将两个字符串合并为一个,并用分隔符隔开.之后跑后缀数组,求出height[],for一遍,找到在分隔符两侧的height值最大的便是答案. 代码: // poj2774 #include<algorithm> #include<iostream> #inc

【POJ2774】Long Long Message 后缀自动机

--另一道题用到,想看看部分代码对不对.于是又拿SAM交了一遍此题. 仅贴代码. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 101000 #define T 30 using namespace std; char s[N],t[N]; int pa[N<<1],son[N<<1][T]; int de

laravel 【error】MethodNotAllowedHttpException No message

Symfony \ Component \ HttpKernel \ Exception \ MethodNotAllowedHttpException No message 报错原因[原理]CSRF防护: 在 web 路由文件中所有请求方式为PUT.POST或DELETE的HTML表单都会包含一个CSRF令牌字段,否则,请求会被拒绝 解决办法: 在html表单提交中加入: {{csrf_field()}}或者 <input type="hidden" name="_t

【JAVASCRIPT】获取触发MESSAGE事件的源IFRAME

先让发送源获取焦点,然后获取焦点元素. window.addEventListener('message',function(msg){ //做一些事来判断是不是某个iframe发送的消息 msg.source.focus(); var sourceFrame=document.activeElement; }); 如果不想影响焦点的话,可以遍历一遍所有的iframe function findIframe(win){ var fs=document.querySelectorAll('ifra

【POJ3693】Maximum repetition substring (SA)

这是一道神奇的题目..论文里面说得不清楚,其实是这样...如果一个长度为l的串重复多次,那么至少s[1],s[l+1],s[2*l+1],..之中有相邻2个相等...设这时为j=i*l+1,k=j+l,我们这时候借助SA和RMQ  O(1)求出:m=lcp(j,k),这时候,重复次数至少ans=m div l+1 .  当然,我们枚举到不一定能够是最优啊,因为你枚举的不一定是字符串的首尾..那这时候怎么办?就是论文里面说的,向前和向后匹配.我们设t=l-m mod l..可以理解为,这时候 m

【SPOJ694】Distinct Substrings (SA)

求不相同子串个数    该问题等价于求所有后缀间不相同前缀的个数..也就是对于每个后缀suffix(sa[i]),将贡献出n-sa[i]+1个,但同时,要减去那些重复的,即为height[i],故答案为n-sa[i]+1-height[i]的累计. const maxn=1419; var x,y,rank,sa,h,c:array[0..maxn] of longint; s:ansistring; t,q,n:longint; function max(x,y:longint):longin

【原创】NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战

前言 本文将演示一个iOS客户端程序,通过UDP协议与两个典型的NIO框架服务端,实现跨平台双向通信的完整Demo.服务端将分别用MINA2和Netty4进行实现,而通信时服务端你只需选其一就行了.同时用MINA2和Netty4分别实现服务端的目的,是因为很多人都在纠结到底是用MINA还是Netty来实现高并发的Java网络通信服务端,在此干脆两个都实现了,就看你怎么选择了,够吊吧. NIO框架的流行,使得开发大并发.高性能的互联网服务端成为可能.这其中最流行的无非就是MINA和Netty了,M

BeanShell用法汇总(部分摘抄至网络)【转】

说明:本文部分资料摘抄至 来源: http://www.cnblogs.com/puresoul/p/4915350.html 来源: http://www.cnblogs.com/puresoul/p/4949889.html 来源: http://blog.csdn.net/silencemylove/article/details/51373873 一.什么是Bean Shell BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法; BeanShel