转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud

Long Long Message
Time Limit: 4000MS   Memory Limit: 131072K
Case Time Limit: 1000MS

Description

The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes to him these days: his mother is getting ill. Being worried about spending so much on railway tickets (Byterland is such a big country, and he has to spend 16 shours on train to his hometown), he decided only to send SMS with his mother.

The little cat lives in an unrich family, so he frequently comes to the mobile service center, to check how much money he has spent on SMS. Yesterday, the computer of service center was broken, and printed two very long messages. The brilliant little cat soon found out:

1. All characters in messages are lowercase Latin letters, without punctuations and spaces. 
2. All SMS has been appended to each other – (i+1)-th SMS comes directly after the i-th one – that is why those two messages are quite long. 
3. His own SMS has been appended together, but possibly a great many redundancy characters appear leftwards and rightwards due to the broken computer. 
E.g: if his SMS is “motheriloveyou”, either long message printed by that machine, would possibly be one of “hahamotheriloveyou”, “motheriloveyoureally”, “motheriloveyouornot”, “bbbmotheriloveyouaaa”, etc. 
4. For these broken issues, the little cat has printed his original text twice (so there appears two very long messages). Even though the original text remains the same in two printed messages, the redundancy characters on both sides would be possibly different.

You are given those two very long messages, and you have to output the length of the longest possible original text written by the little cat.

Background: 
The SMS in Byterland mobile service are charging in dollars-per-byte. That is why the little cat is worrying about how long could the longest original text be.

Why ask you to write a program? There are four resions: 
1. The little cat is so busy these days with physics lessons; 
2. The little cat wants to keep what he said to his mother seceret; 
3. POJ is such a great Online Judge; 
4. The little cat wants to earn some money from POJ, and try to persuade his mother to see the doctor :( 

Input

Two strings with lowercase letters on two of the input lines individually. Number of characters in each one will never exceed 100000.

Output

A single line with a single integer number – what is the maximum length of the original text written by the little cat.

Sample Input

yeshowmuchiloveyoumydearmotherreallyicannotbelieveit
yeaphowmuchiloveyoumydearmother

Sample Output

27

Source

POJ Monthly--2006.03.26,Zeyuan Zhu,"Dedicate to my great beloved mother."

题意:

求两个字符串的最长公共子串。

分析:

将两个字符串中间用一个不会出现的'$'符号连接,然后求出lcp,最大的且相邻的两个后缀不属于同一个字符串的就是答案。

用的是DC3

 #include <iostream>
#include <sstream>
#include <ios>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <vector>
#include <string>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <climits>
#include <cctype>
using namespace std;
#define XINF INT_MAX
#define INF 0x3FFFFFFF
#define MP(X,Y) make_pair(X,Y)
#define PB(X) push_back(X)
#define REP(X,N) for(int X=0;X<N;X++)
#define REP2(X,L,R) for(int X=L;X<=R;X++)
#define DEP(X,R,L) for(int X=R;X>=L;X--)
#define CLR(A,X) memset(A,X,sizeof(A))
#define IT iterator
typedef long long ll;
typedef pair<int,int> PII;
typedef vector<PII> VII;
typedef vector<int> VI;
#define MAXN 400010 #define F(x) ((x)/3+((x)%3==1?0:tb))
#define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)
int wa[MAXN*],wb[MAXN*],wv[MAXN*],ww[MAXN*]; int c0(int *r, int a, int b) {
return r[a]==r[b]&&r[a+]==r[b+]&&r[a+]==r[b+];
}
int c12(int k, int *r, int a, int b)
{
if(k==) return r[a]<r[b]||r[a]==r[b]&&c12(,r,a+,b+);
else return r[a]<r[b]||r[a]==r[b]&&wv[a+]<wv[b+];
}
void rsort(int *r, int *a, int *b, int n, int m) {
REP(i,n) wv[i]=r[a[i]];
REP(i,m) ww[i]=;
REP(i,n) ww[wv[i]]++;
REP(i,m-) ww[i+]+=ww[i];
DEP(i,n-,) b[--ww[wv[i]]]=a[i];
} void dc3(int *r, int *sa, int n, int m) {
int j,*rn=r+n,*san=sa+n,ta=,tb=(n+)/,tbc=,p;
r[n]=r[n+]=;
REP(i,n) if(i%!=) wa[tbc++]=i;
rsort(r+,wa,wb,tbc,m);
rsort(r+,wb,wa,tbc,m);
rsort(r,wa,wb,tbc,m);
for(p=,rn[F(wb[])]=,j=;j<tbc;j++)
rn[F(wb[j])]=c0(r,wb[j-],wb[j])?p-:p++;
if(p<tbc) dc3(rn,san,tbc,p);
else REP(i,tbc) san[rn[i]]=i;
REP(i,tbc) if(san[i]<tb) wb[ta++]=san[i]*;
if(n%==) wb[ta++]=n-;
rsort(r,wb,wa,ta,m);
REP(i,tbc) wv[wb[i]=G(san[i])]=i;
int i;
for(i=j=p=;i<ta&&j<tbc;p++)
sa[p]=c12(wb[j]%,r,wa[i],wb[j])?wa[i++]:wb[j++];
for(;i<ta;p++) sa[p]=wa[i++];
for(;j<tbc;p++) sa[p]=wb[j++];
} int ra[MAXN*], height[MAXN*];
void calheight(int *r,int *sa,int n) {
int i,j,k=;
for(i=;i<=n;i++) ra[sa[i]]=i;
for(i=;i<n;height[ra[i++]]=k)
for(k?k--:,j=sa[ra[i]-];r[i+k]==r[j+k];k++);
}
int sa[MAXN *];
char str[MAXN];
char s[MAXN];
int a[MAXN];
int main()
{
ios::sync_with_stdio(false);
while(scanf("%s",str)!=EOF){
scanf("%s",s);
int len2=strlen(s);
int len1=strlen(str);
for(int i=;i<len2;i++){
str[i+len1]=s[i];
}
str[len1+len2]='\0';
int len=len1+len2;
for(int i=;i<len;i++){
a[i]=str[i]-'a'+;
}
a[len]=;
dc3(a,sa,len+,);
calheight(a,sa,len);
int ans=;
for(int i=;i<len;i++){
if(sa[i]<len1&&sa[i-]>=len1||(sa[i]>=len1&&sa[i-]<len1)){
ans=max(height[i],ans);
}
}
printf("%d\n",ans);
} return ;
}

代码君

利用后缀自动机的话,以一个串建一个自动机,然后另一个串直接塞进去跑就行了。相当裸

 #include <iostream>
#include <sstream>
#include <ios>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <vector>
#include <string>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <climits>
#include <cctype>
using namespace std;
#define XINF INT_MAX
#define INF 0x3FFFFFFF
#define MP(X,Y) make_pair(X,Y)
#define PB(X) push_back(X)
#define REP(X,N) for(int X=0;X<N;X++)
#define REP2(X,L,R) for(int X=L;X<=R;X++)
#define DEP(X,R,L) for(int X=R;X>=L;X--)
#define CLR(A,X) memset(A,X,sizeof(A))
#define IT iterator
#define RIT reverse_iterator
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<PII> VII;
typedef vector<int> VI;
#define X first
#define Y second
#define lson(X) ((X)<<1)
#define rson(X) ((X)<<1|1) #define MAXN 100010 //#define SUFFIX_TREE struct SAM{
SAM* go[];
SAM* par;
int maxl;
#ifdef SUFFIX_TREE
int st_head;
#endif
SAM(int l=):maxl(l) {
#ifdef SUFFIX_TREE
st_head = ;
#endif
}
SAM& operator=(const SAM& s){
maxl = s.maxl;
par = s.par;
memcpy(go, s.go, sizeof(go));
return *this;
#ifdef SUFFIX_TREE
st_head = s.st_head;
#endif
}
int minl() {
return par?par->maxl+:maxl;
}
} node[MAXN<<], *last, *root;
int n_node; SAM* newnode() {
return &node[n_node++];
} void init_sam() {
n_node = ;
last = root = newnode();
} void extend(int c) {
SAM* p = last, *np = newnode();
np->maxl = p->maxl + ;
for(; p && !p->go[c]; p = p->par) p->go[c] = np;
if(!p) np->par = root;
else {
SAM* q = p->go[c];
if(q->maxl == p->maxl + ) np->par = q;
else {
SAM* nq = newnode();
*nq = *q;
nq->maxl = p->maxl + ;
np->par = q->par = nq;
for(;p && p->go[c] == q ;p = p->par) p->go[c] = nq;
}
}
last = np;
#ifdef SUFFIX_TREE
last->st_head = ;
#endif
} string str; #ifdef SUFFIX_TREE VI Map[MAXN<<]; void init_suffixtree(char* s) {
init_sam();
int l = strlen(s);
REP(i,l) extend(s[l-i-]);
REP(i,n_node) Map[i].clear();
REP(i,n_node) if(node[i].st_head) {
SAM* p = &node[i];
while(p!=root) {
string ss = str.substr(p->minl()-,p->maxl-p->minl()+);
reverse(ss.begin(),ss.end());
cout<<ss<<" -> ";
p=p->par;
}
cout<<"|"<<endl;
}
} #endif char s[MAXN]; int main()
{
while(~scanf("%s",s)) {
init_sam();
for(int i=;s[i];i++) extend(s[i]-'a');
scanf("%s",s);
int ans = ;
int l = ;
SAM* now = root;
for(int i=;s[i];i++) {
s[i]-='a';
while(now!=root && now->go[s[i]]==NULL) {
now = now->par;
l = min(l, now->maxl);
}
l++;
if(now->go[s[i]]) now = now->go[s[i]];
else l=;
ans = max(ans, l);
}
printf("%d\n", ans);
}
return ;
}

代码君

poj2774 Long Long Message(后缀数组or后缀自动机)的更多相关文章

  1. [TJOI2015]弦论(后缀数组or后缀自动机)

    解法一:后缀数组 听说后缀数组解第k小本质不同的子串是一个经典问题. 把后缀排好序后第i个串的本质不同的串的贡献就是\(n-sa[i]+1-LCP(i,i-1)\)然后我们累加这个贡献,看到哪一个串的 ...

  2. (持续更新)虚树,KD-Tree,长链剖分,后缀数组,后缀自动机

    真的就是讲课两天,吸收一个月呢! \(1.\)虚树 \(2.\)KD-Tree \(3.\)长链剖分 \(4.\)后缀数组 后缀数组 \(5.\)后缀自动机 后缀自动机

  3. poj 2774 最长公共子--弦hash或后缀数组或后缀自己主动机

    http://poj.org/problem?id=2774 我想看看这里的后缀数组:http://blog.csdn.net/u011026968/article/details/22801015 ...

  4. hdu4436-str2int(后缀数组 or 后缀自动机)

    题意:给你一堆字符串,仅包含数字'0'到'9'. 例如 101 123 有一个字符串集合S包含输入的N个字符串,和他们的全部字串. 操作字符串很无聊,你决定把它们转化成数字. 你可以把一个字符串转换成 ...

  5. 字符串数据结构模板/题单(后缀数组,后缀自动机,LCP,后缀平衡树,回文自动机)

    模板 后缀数组 #include<bits/stdc++.h> #define R register int using namespace std; const int N=1e6+9; ...

  6. 后缀数组(suffix array)详解

    写在前面 在字符串处理当中,后缀树和后缀数组都是非常有力的工具. 其中后缀树大家了解得比较多,关于后缀数组则很少见于国内的资料. 其实后缀数组是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现, ...

  7. 字符串 --- KMP Eentend-Kmp 自动机 trie图 trie树 后缀树 后缀数组

    涉及到字符串的问题,无外乎这样一些算法和数据结构:自动机 KMP算法 Extend-KMP 后缀树 后缀数组 trie树 trie图及其应用.当然这些都是比较高级的数据结构和算法,而这里面最常用和最熟 ...

  8. bzoj 3172 后缀数组|AC自动机

    后缀数组或者AC自动机都可以,模板题. /************************************************************** Problem: 3172 Us ...

  9. 数据结构之后缀数组suffix array

    在字符串处理当中,后缀树和后缀数组都是非常有力的工具,其中后缀树大家了解得比较多,关于后缀数组则很少见于国内的资料.其实后缀是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现,能够实现后缀树的很多 ...

随机推荐

  1. OpenGL ES 2.0 曲面物体的构建

    球体构建的基本原理构建曲面物体最重要的就是找到将曲面恰当拆分成三角形的策略. 最基本的策略是首先按照一定的规则将物体按行和列两个方向进行拆分,这时就可以得到很多的小四边形.然后再将每个小四边形拆分成两 ...

  2. HDU 5904 - LCIS (BestCoder Round #87)

    HDU 5904 - LCIS [ DP ]    BestCoder Round #87 题意: 给定两个序列,求它们的最长公共递增子序列的长度, 并且这个子序列的值是连续的 分析: 状态转移方程式 ...

  3. Render和template?

    Template是一个模板. render = web.template.render('templates/') 这会告诉web.py到你的模板目录中去查找模板.然后把 index.GET改成: 告 ...

  4. html5 百分比计算

    这几天一直在看html5,看到了百分比的计算公式:目标元素的尺寸/上下文元素的尺寸=百分比尺寸.看到这个公式,有点懂,但是有不明白.对于目标元素很容易理解,但是对于上下文元素就不是很好理解了.试了一些 ...

  5. 做好织梦dedecms安全防护全部方法

    很多同学遇到网站被攻击挂马,大都不是竞争对手所为.多数情况下是黑客利用工具批量扫描入侵的.因此安全防护自关重要. 织梦安装时注意: 修改默认数据库前缀: 在dedecms安装的时候修改下数据库的表前缀 ...

  6. a标签href不跳转 禁止跳转

    a标签href不跳转 禁止跳转 当页面中a标签不需要任何跳转时,从原理上来讲,可分如下两种方法: 标签属性href,使其指向空或不返回任何内容.如: <a href="javascri ...

  7. easyui 添加dialog

    javascript //查看角色所属用户 function roleuser(obj, id) { var C_ID = id; var Url = "/Sys/RoleUserName& ...

  8. Using ROWNUM in Oracle

    ROWNUM is an Oracle pseudo column which numbers the rows in a result set. SELECT rownum, table_nameF ...

  9. XML Schema <第三篇>

    验证XML文档是否符合议定的XML结构有两种方法,分别是DTD模式与XML Schema.本文主要介绍XML Schema. 一.XML Schema的优点 XML Schema基于XML,没有专门的 ...

  10. linux awk 使用

    awk是linux下的一个命令,他对其他命令的输出,对文件的处理都十分强大,其实他更像一门编程语言,他可以自定义变量,有条件语句,有循环,有数组,有正则,有函数等.他读取输出,或者文件的方式是一行,一 ...