大致题意:
求两个字符串的最长公共子串。
大致思路:
后缀数组+二分……水水,真心喜欢ural题目分类功能Orz
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int nMax=500000;
int num[nMax];
int sa[nMax], rank[nMax], height[nMax];
int wa[nMax], wb[nMax], wv[nMax], wd[nMax];
int cmp(int *r, int a, int b, int l){
return r[a] == r[b] && r[a+l] == r[b+l];
}
void da(int *r, int n, int m){ // 倍增算法 r为待匹配数组 n为总长度 m为字符范围
int i, j, p, *x = wa, *y = wb, *t;
for(i = 0; i < m; i ++) wd[i] = 0;
for(i = 0; i < n; i ++) wd[x[i]=r[i]] ++;
for(i = 1; i < m; i ++) wd[i] += wd[i-1];
for(i = n-1; i >= 0; i --) sa[-- wd[x[i]]] = i;
for(j = 1, p = 1; p < n; j *= 2, m = p){
for(p = 0, i = n-j; i < n; i ++) y[p ++] = i;
for(i = 0; i < n; i ++) if(sa[i] >= j) y[p ++] = sa[i] - j;
for(i = 0; i < n; i ++) wv[i] = x[y[i]];
for(i = 0; i < m; i ++) wd[i] = 0;
for(i = 0; i < n; i ++) wd[wv[i]] ++;
for(i = 1; i < m; i ++) wd[i] += wd[i-1];
for(i = n-1; i >= 0; i --) sa[-- wd[wv[i]]] = y[i];
for(t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i < n; i ++){
x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p - 1: p ++;
}
}
}
void calHeight(int *r, int n){ // 求height数组。
int i, j, k = 0;
for(i = 1; i <= n; i ++) rank[sa[i]] = i;
for(i = 0; i < n; height[rank[i ++]] = k){
for(k ? k -- : 0, j = sa[rank[i]-1]; r[i+k] == r[j+k]; k ++);
}
}
int loc[nMax],m;
char str[nMax],res[nMax];
bool vis[1004];
bool check(int mid,int len){
int i,j,tot;
tot=0;
memset(vis,0,sizeof(vis));
for(i=2;i<=len;i++){
if(height[i]<mid){
memset(vis,0,sizeof(vis));
tot=0;
}
else{
if(!vis[loc[sa[i-1]]]){
vis[loc[sa[i-1]]]=1;
tot++;
}
if(!vis[loc[sa[i]]]){
vis[loc[sa[i]]]=1;
tot++;
}
if(tot==2){
for(j=0;j<mid;j++){
res[j]=num[sa[i]+j];
}res[mid]='\0';
return 1;
}
}
}
return 0;
}
int main(){
int n,k,i,j,a,b,sp,ans,len;
while(scanf("%d",&len)&&len){
sp=150; //分隔符
n=0;
m=2;
ans=0;
for(i=1;i<=2;i++){
scanf("%s",str);
for(j=0;str[j];j++){
loc[n]=i;
num[n++]=str[j];
}
loc[n]=sp;
num[n++]=sp++;
}
num[n]=0;
da(num, n + 1, sp+4);
calHeight(num,n);
int left=0,right=len,mid;//开始二分
while(right>=left){
mid=(right+left)/2;
if(check(mid,n)){ //判断长度为mid的串是否是所有字符串的公共子串
left=mid+1;
ans=mid;
}
else{
right=mid-1;
}
}
if(ans!=0){
printf("%s\n",res);
}
else{
printf("\n");
}
break;
}
return 0;
}
分享到:
相关推荐
- **后缀数组**和**高度数组**:在字符串处理问题中,如PKU 2774和PKU 1743,后缀数组和高度数组用于找到最长公共前缀或最长不可重叠重复子串。 - **二分查找**:在多个题目中,如寻找第K大的数或判断子串是否存在...
《Ural URAL 解题思路》 在编程竞赛和算法挑战的世界中,Ural University的在线判题系统,简称Ural或URAL,是许多程序员磨炼技能的重要平台。它提供了丰富的算法题目,涵盖数据结构、图论、动态规划、数学等多个...
例如URAL1470 UFOs问题,可以通过三维树状数组来高效解决。 3. **线段树**: - 线段树是一种数据结构,可以用于在线性时间内处理区间查询和区间更新。在POJ2482 Stars in Your Window问题中,由于数值范围很大,...
标题 "acm_ural_1148" 指向的是一个 ACM(国际大学生程序设计竞赛)问题,这个问题在 Ural University Online Judge(乌拉尔大学在线评测系统)上编号为 1148。描述中的 "Pascal acm_timus_ural_1148.pas" 表明提供...
"Ural"是一款字体,可能是指一种特定的中文字体或者西文字体设计。在IT领域,字体扮演着至关重要的角色,特别是在图形设计、网页设计、出版印刷以及各种视觉传达中。字体的选择能够极大地影响信息的呈现效果和用户...
通过分析后缀数组的性质可知,最长的公共前缀一定会出现在后缀数组中相邻位置的两个后缀之间,即height[i]表示了这两个后缀之间的最长公共前缀。因此,只需要遍历后缀数组,检查每一对相邻的后缀是否来自不同的原始...
URAL部分测试数据是针对Timus Online Judge平台的一个竞赛或练习问题的数据集。Timus Online Judge是一个流行的在线编程竞赛和练习平台,它为参赛者提供了一系列的编程题目,以提升编程技能和算法理解能力。这个数据...
"URAL3D"是一个与字体相关的主题,这通常指的是一个特定的三维字体设计或字体库。在计算机领域,字体是用于显示和打印文本的图形表示。它们由一系列字符形状组成,包括字母、数字和标点符号,每个都有其独特的样式和...
"ural部分题解"是一个关于编程竞赛平台Ural(也称为URAL Online Judge或University of Maribor Algorithmic contests)的解题集,由大牛出品。这个资源包含Vol1到Vol3的部分题目解答,虽然不完整,但大约涵盖了200道...
Ural1028 Star 密码机(浙江2003省赛)
### Ural Volume I 题解 by yuhch123 #### 关于 yuhch123 yuhch123 是一位在 IT 和编程竞赛领域内有着卓越成就的人物,曾在 IOI 2008 中荣获金牌第一名。这份文档是他针对 Ural 编程题库第一卷的解答,对于学习算法...
HDU、PKU和URAL是三个著名的在线编程竞赛平台,它们为程序员提供了丰富的算法题目,帮助参赛者提升编程技能和算法理解能力。这些平台的题目通常涵盖了基础算法、数据结构、数学逻辑等多个方面,对于准备各类编程竞赛...
【标题】"acm_ural_1099" 是一个与编程竞赛相关的主题,通常在ACM(国际大学生程序设计竞赛)或类似的算法比赛中出现。这类问题旨在测试参赛者解决算法问题的能力,通常需要使用一种或多种编程语言来编写解决方案。 ...
《URAL题解》是针对ACM(国际大学生程序设计竞赛)中URAL在线判题系统题库的详尽解析,涵盖了从Vol_I到Vol_III的所有题目。这些文档旨在帮助参赛者理解和解决各种算法问题,提升编程技能,为比赛做好充分准备。 ...
Ural 1238 源代码 涉及算法(动态规划、贪心、DFS)
**Ural开源库详解** Ural是一个开源的C++库,专为实现高效、灵活的线性代数计算而设计。这个库的核心特性是利用模板类来表示不同等级的张量,包括标量、向量(等级1)、矩阵(等级2)以及更高阶的张量(如等级3)。...
Ural ACM通常指的是乌拉尔大学(University of Ural)举办的算法竞赛,这类比赛旨在提升参赛者在算法设计、数据结构以及问题解决能力上的技能。在这个压缩包中,我们有针对Ural ACM 1000题目的解决方案,这些代码...
- **HDU 2492**:使用树状数组进行处理,计算出前面比它大、比它小、后面比它大、比它小的数,然后进行乘法运算。 - **POJ 3225**:涉及到区间扩大两倍表示点和线段,还需要支持异或操作和覆盖操作。解决此类问题的...
资源分类:Python库 所属语言:Python 资源全名:ural-0.28.0.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
URAL-PHA是一个与字体相关的主题。在这个压缩包中,我们看到只有一个文件名“2238”,这可能是某种特定字体的文件或者一个包含了多个字体文件的集合。在IT行业中,字体设计是用户界面和视觉传达的重要组成部分,尤其...