`
darren_nizna
  • 浏览: 72791 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

[PKU/POJ][3294][Life Forms][后缀数组]

J# 
阅读更多

给你 n 个字符串,求出最长的子串,使得子串在大于一半的字符串中都出现。

先将 n 个字符串用 n 个不同的字符连接起来。求出 height 数组后,二分子串长度 k, 查找是否存在连续的大于 n/ 2+ 1 个后缀的 height 值都大于 k。这里要求这 n/ 2+ 1 都属于不同串,可以用一数组进行标记,具体做法详见代码。

代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>

int const N= 200100;
int wa[N], wb[N], wv[N], ws[N];
int rank[N], height[N], sa[N], r[N], n, m;
int num[N], idx= 0, ins= 128;
int cnt[1010];
char str[1010];

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* sa, int n, int m ){
	int i, j, p, *x= wa, *y= wb, *t;
	for( i= 0; i< m; ++i ) ws[i]= 0;
	for( i= 0; i< n; ++i ) ws[ x[i]= r[i] ]++;
	for( i= 1; i< m; ++i ) ws[i]+= ws[i-1];
	for( i= n- 1; i>= 0; i-- ) sa[ --ws[ 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 ) ws[i]= 0;
		for( i= 0; i< n; ++i ) ws[ wv[i] ]++;
		for( i= 1; i< m; ++i ) ws[i]+= ws[i-1];
		for( i= n- 1; i>= 0; i-- ) sa[ --ws[ wv[i] ] ]= y[i];
		
		t= x, x= y, y= t; p= 1; x[ sa[0] ]= 0;
		for( i= 1; i< n; ++i )
		x[ sa[i] ]= cmp( y, sa[i-1], sa[i], j )? p- 1: p++;
	}
}

void calheight( int* r, int* sa, int n ){
	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 check( int mid ){
	for( int i= 0; i<= 1000; ++i ) cnt[i]= 0;
	int flag= 1, ans= 0;
	
	for( int i= 1; i<= n; ++i ){
		if( height[i]< mid ){
			cnt[ num[ sa[i] ] ]= ++flag; ans= 1;
		}
		else{
			if( cnt[ num[ sa[i] ] ]!= flag ) ans++;
			cnt[ num[ sa[i] ] ]= flag;
		}
		if( ans>= ( m/ 2+ 1) ) return 1;
	}
	return 0;
}

void print( int mid ){
	for( int i= 0; i<= 1000; ++i ) cnt[i]= 0;
	int ans= 0, flag= 1, isp= 0, beg;
	
	for( int i= 1; i<= n; ++i ){
		if( height[i]< mid ){
			cnt[ num[ sa[i] ] ]= ++flag; ans= 1; isp= 0; beg= sa[i];
		}
		else{
			if( cnt[ num[ sa[i] ] ]!= flag ) ans++;
			cnt[ num[ sa[i] ] ]= flag;
		}
		
		if( isp== 0 && ans>= (m/ 2+ 1 ) ){
			isp= 1;
			
			for( int j= 0; j< mid; ++j )
			printf("%c", r[ beg+ j] );
			
			puts("");
		}
	}
}

int main(){
	while( scanf("%d",&m)!= EOF ){
		getchar();
		if( m== 0 ) return 0;
		
		n= 0; ins= 128; idx= 0;
		for( int i= 0; i< m; ++i ){
			gets(str);
			int len= strlen(str); ++idx;
			for( int i= 0; i< len; ++i ) {
				num[n+ i]= idx; r[n+ i]= str[i]; }
			
			r[len+ n]= ins++;  len++; n+= len;
		}
		n--; r[n]= 0;
		
		da( r, sa, n+ 1, 500 );
		calheight( r, sa, n );		
		
		int left= 1, right= n;
		while( left<= right ){
			int mid= (left+ right)>>1;
			
			if( check( mid ) ) left= mid+ 1;
			else right= mid- 1;
		}
		
		if( right== 0 ) puts("?");
		else print( right );
		
		puts("");
	}
	
	return 0;
}
 
1
1
分享到:
评论

相关推荐

    PKU 、POJ ACM/ICPC300多题的代码

    标题“PKU 、POJ ACM/ICPC300多题的代码”指的是北京大学(PKU)和编程在线评测平台POJ上收集的300多道ACM/ICPC(国际大学生程序设计竞赛)比赛题目解题代码。这个压缩包包含了解决这些竞赛问题的算法和程序实现,是...

    PKU_poj 1197

    ACM PKU_poj 1197 仓库问题源代码,愿与大家共享。若谁更好的代码,多谢提供。

    PKU_poj 1001~1009

    标题“PKU_poj 1001~1009”揭示了这是一组与北京大学(Peking University)编程竞赛平台POJ相关的解决方案。在这个压缩包中,包含了从问题1001到1009的C++源代码,表明这些代码已经过验证并成功解决了对应的算法问题。...

    pku(poj)--2494--Acid Text--java代码

    根据给定的文件信息,我们可以总结出以下关于POJ(PKU)问题2494“Acid Text”以及其Java代码实现的关键知识点: ### 1. POJ(PKU)2494:Acid Text POJ(Peking University Online Judge)是北京大学的一个在线...

    POJ动态规划题目全面总结

    PKU Online Judge上面很全面的动态规划试题总结。动态规划是ACM考点中最重要的一大类算法之一,对于工作人员来说,动态规划也是实际开发中经常会遇到的算法。这是POJ上面很多DP题目的总结与深刻分析。利于算法学习,...

    pku_poj_2187.rar_poj 2187_凸包问题

    标题中的“pku_poj_2187.rar_poj 2187_凸包问题”表明这是一个关于北京大学(Peking University, PKU)编程竞赛平台POJ上的第2187题,题目主要涉及凸包问题。描述中的“O(nlogn)凸包问题 poj2187”提示我们解决这个...

    pku1088.rar_pku 10_pku 1088_poj 1088

    标题中的“pku1088.rar_pku 10_pku 1088_poj 1088”指的是北京大学(Peking University, PKU)编程竞赛中的第1088题,也称为POJ(Peking University Online Judge)的1088题。这个题目在编程竞赛社区中通常有一个特定的...

    pku1151.rar_Atlantis_pku 11_poj Atlant_poj Atlantis_poj11

    标题中的“pku1151.rar_Atlantis_pku 11_poj Atlant_poj Atlantis_poj11”似乎是指北京大学(Peking University, PKU)编程竞赛中的一道题目,编号为1151,与“Atlantis”这个主题相关。这道题目在多个平台上也被提及...

    Suffix小结.txt

    ### 后缀数组(Suffix Array)详解 #### 引言 后缀数组是计算机科学领域内一种高效的数据结构,主要用于字符串处理,特别是模式匹配、文本分析等场景。它能够快速定位一个子串在主串中的位置,对于解决复杂的字符...

    PKU1639解题报告

    - **倍增算法**:通过构建k-前缀排序的后缀数组(SA_k)及其对应的名次数组(Rank_k),逐步增加k的值,最终得到完整的后缀数组。这种方法的时间复杂度更优。 #### 解题步骤 1. **字符串处理**:将所有的输入字符...

    poj3252.rar_pku 3252_poj32

    标题中的"poj3252.rar_pku 3252_poj32"表明这是一个与编程竞赛相关的资源,具体来说是北京大学(PKU)ACM竞赛中的问题3252。"poj"通常指的是"Programming Online Judge",这是一个在线编程比赛平台,而"Pku"则代表...

    poj 130题 acm pku

    【标题】"poj 130题 acm pku" 涉及的是ACM(国际大学生程序设计竞赛)中的PKU(北京大学)在线判题系统POJ(Problem Online Judge)的相关题目。ACM/ICPC(International Collegiate Programming Contest)是全球...

    poj(PKU-2314-POJ language

    根据提供的文件信息,我们可以分析出该段代码是用于解决POJ平台上的2314题的一种解决方案,主要涉及到了变量管理、表达式处理等方面。下面将详细解释代码中的关键概念和实现逻辑。 ### 关键概念解析 #### Variable...

    PKU POJ 1162 Building with Blocks解题报告

    ### PKU POJ 1162 Building with Blocks 解题报告 #### 题目概述 本题名为“Building with Blocks”,属于经典的积木搭建问题。题目要求利用一定数量的基本单位积木,搭建出特定的三维形状。积木的种类不超过12种,...

    北大oj题集(清晰版,poj上原题集)

    “北京大学程序在线评测系统”是一个免费的公益性网上程序设计题库,网址为http://poj.grids.cn/ 及 http://acm.pku.edu.cn/JudgeOnline,它包含2000多道饶有趣味的程序设计题,题目大部分来自ACM国际大学生程序设计...

    pku 123 题目代码

    标题 "pku 123 题目代码" 暗示了这是一个与北京大学(Peking University)编程竞赛(PKU ACM/ICPC)相关的代码集合,可能包含了参赛者为解决PKU ACM在线判题系统(PJU POJ)上的123道题目所编写的程序。POJ是北京大学维护...

    pku poj 2406

    #include using namespace std; #define M 1000000 char t[M+1],p[M+1]; int lent,lenp; bool kmp(char *t,char *p) { int i,j; for(i=lenp,j=0;i;i++) { if(t[i]!=p[j]) return false;...}

    poj pku图论、网络流入门题总结、汇总

    根据提供的标题“poj pku图论、网络流入门题总结、汇总”及描述“很经典的图论,网络流入门的题目,值得一看啊~~其中有简单的解析”,本篇将对这些经典图论与网络流问题进行详细的分析和总结。通过梳理各题目及其...

    ACM算法模板和pku代码

    本科参加ACM竞赛的过程中积累下来的一部分算法模板,和自己在PKU上面做的一部分题目。 模板目录结构: 目录: 动态规划 O(n^2)的最长上升子序列 ... 后缀数组,分三段,分别倒转,字典序最小 AC自动机实现多串匹配

    POJ.rar_pku ac_pku.1050

    标题中的"POJ.rar_pku ac_pku.1050"暗示了这是一个与北京大学(Peking University, 简称PKU)编程竞赛相关的压缩文件,其中包含了作者通过验证(Passed All Cases, 简称AC)的代码,具体是针对PKU题目编号1050的问题。...

Global site tag (gtag.js) - Google Analytics