POJ 2217:Secretary(后缀数组)

题目大意:求两个字符串的公共子串。

分析:

模板题,将两个字符串接起来用不会出现的字符分割,然后求分属两个字符串的相邻后缀lcp的最大值即可。

代码:

program work;
type
  arr=array[0..20001]of longint;
var
  sa,rank,b,tmp,lcp:arr;
  n,i,m,l,u,ans,t:longint;
  s,s1,s2:ansistring;
  ch:char;
function compare(i,j,k:longint):longint;
var ri,rj:longint;
begin
  if rank[i]<>rank[j] then exit(ord(rank[i]<rank[j]))
   else
     begin
       if i+k<=n then ri:=rank[i+k] else ri:=-1;
       if j+k<=n then rj:=rank[j+k] else rj:=-1;
       exit(ord(ri<rj));
     end;
end;
procedure qsort(l,h,k:longint; var a:arr);
var i,j,t,m:longint;
begin i:=l; j:=h;
  m:=a[(i+j) div 2];
 repeat
while compare(a[i],m,k)=1 do inc(i);
while compare(m,a[j],k)=1 do dec(j);
if i<=j then
 begin   t:=a[i]; a[i]:=a[j]; a[j]:=t;
inc(i); dec(j);  end;  until i>j;
 if i<h then qsort(i,h,k,a); if j>l then qsort(l,j,k,a);  end;
procedure work_sa(s:ansistring; var sa:arr);
var k,i:longint;
begin
  for i:=1 to n do begin sa[i]:=i;  rank[i]:=ord(s[i]); end;
  k:=1;
  while k<=n do
   begin
     qsort(1,n,k,sa);
     tmp[sa[1]]:=1;
     for i:=2 to n do
       tmp[sa[i]]:=tmp[sa[i-1]]+compare(sa[i-1],sa[i],k);
     rank:=tmp;
     k:=k*2;
   end;
end;
function max(x,y:longint):longint;
begin
   if x>y then max:=x else max:=y;
end;
procedure work_lcp(s:ansistring;var sa,lcp:arr);
var i,j,h:longint;
begin
  for i:=1 to n do rank[sa[i]]:=i;
  h:=0; lcp[1]:=0; sa[0]:=0;rank[0]:=0;
  for i:=1 to n do
   begin
     j:=sa[rank[i]-1];
     if h>0 then dec(h);
     while (i+h<=n)and(j+h<=n) do
      begin
        if s[i+h]<>s[j+h] then break; inc(h);
      end;
     lcp[rank[i]-1]:=h;
   end;
end;
begin
  readln(u);
  for l:=1 to u do
   begin
     readln(s1); readln(s2);
     s:=s1+‘@‘+s2;
     t:=length(s1);
     n:=length(s); work_sa(s,sa);
     work_lcp(s,sa,lcp); ans:=0;
    for i:=1 to n-1 do begin
      if ((sa[i]<=t)and(sa[i+1]>=t+2))or((sa[i+1]<=t)and(sa[i]>=t+2)) then ans:=max(ans,lcp[i]);
    end;
     writeln(‘Nejdelsi spolecny retezec ma delku ‘,ans,‘.‘);
  end;
end.

时间: 2024-10-09 01:56:24

POJ 2217:Secretary(后缀数组)的相关文章

POJ 2217 Secretary (后缀数组)

题目大意: 计算两个字符串的最长的公共字符串字串的长度. 思路分析: 将两个串合并起来. 然后直接跑后缀数组求出height 然后就可以直接扫描一次height ,加个是不是在一个串中的判断就可以了. #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #define maxn 200005 using namespace std; char str[ma

POJ 1226 Substrings (后缀数组)

题目大意: 问的是m个字符串里,都出现过的子串.子串也可以出现在这个串的逆序串中. 思路分析: 居然wa在全5个 "a" 的数据上. 二分的时候下界不能为0.. 思路大致上是把原串和逆序串全部处理出来,放入str中,然后在每个串中间加一个没有出现过的. 此处注意输入不仅仅是字母. 然后跑一遍后缀数组. 然后用标记计数就好了. #include <iostream> #include <cstdio> #include <algorithm> #inc

POJ 2217 Secretary

Secretary Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: 221764-bit integer IO format: %lld      Java class name: Main The basic condition of success of a political party, it is the good Election Programme.

POJ 2406 KMP/后缀数组

题目链接:http://poj.org/problem?id=2406 题意:给定一个字符串,求由一个子串循环n次后可得到原串,输出n[即输出字符串的最大循环次数] 思路一:KMP求最小循环机,然后就能求出循环次数. #define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<str

poj Common Substrings(后缀数组&amp;单调队列)

Common Substrings Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7082   Accepted: 2355 Description A substring of a string T is defined as: T(i, k)=TiTi+1...Ti+k-1, 1≤i≤i+k-1≤|T|. Given two strings A, B and one integer K, we define S, a

POJ 1743-POJ - 3261~后缀数组关于最长字串问题

POJ 1743 题意: 有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1~~88范围内的整数,现在要找一个重复的主题.“主题”是整个音符序列的一个子串,它需要满足如下条件:1.长度至少为5个音符.2.在乐曲中重复出现.(可能经过转调,“转调”的意思是主题序列中每个音符都被加上或减去了同一个整数值)3.重复出现的同一主题在原序列中不能有重叠部分. 问题类型: 不可重叠最长重复子串 分析: 因为有转调问题,所以可以将相邻音符的差分数组去做 不可重叠最长重复子串 然后

Sequence POJ - 3581 (后缀数组)

Given a sequence, {A1, A2, ..., An} which is guaranteed A1 > A2, ..., An,  you are to cut it into three sub-sequences and reverse them separately to form a new one which is the smallest possible sequence in alphabet order. The alphabet order is defin

后缀数组 POJ 2217 Secretary

题目链接 题意:求两个字符串的最长公共子串 分析:做法是构造新的串是两个串连接而成,中间用没有出现的字符隔开(因为这样才能保证S的后缀的公共前缀不会跨出一个原有串的范围),即newS = S + '$' + T.对其求sa数组和height数组,取最小值的height[i],且两个后缀串属于不同的字符串. #include <cstdio> #include <cstring> #include <algorithm> #include <iostream>

POJ 1743:后缀数组

求满足下列要求的最长子串: 1.长度不小于5 2.出现两次(子串整体加上某个值也算出现一次 3.两次出现无重叠 难处理的是第二个要求:整体增加某个数也算出现一次 稍微思考一下便会得出:整体加上某个值后,相邻数的差值是不变的 所以用一个数组r[i]保存mus[i+1]与mus[i]的差值 这里要注意将差值加上88,使差值始终为正以免在计算sa.rank的时候RE,同时字符集大小也变成了88*2 二分答案的同时将后缀按大于mid height分组,满足要求的子串肯定是同一组内的后缀的公共前缀 用l.

poj 3294(经典后缀数组模板)

Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 9820   Accepted: 2708 Description You may have wondered why most extraterrestrial life forms resemble humans, differing by superficial traits such as height, colour, wrinkles, ea