题目大意:
只有一个测例,测例中给出字符串长度N(1 ≤ N ≤ 100,000),接下来给出两个长度为N的字符串(都由大写字母组成),要求输出最长公共连续子序列。
注释代码:
/*
* Problem ID : URAL 1517 Freedom of Choice
* Author : Lirx.t.Una
* Language : Visual C 2010
* Run Time : 0.171
* Run Memory : 4232KB
*/
#pragma GCC optimize("O2")
#include <stdio.h>
#define CHN 'Z'
#define MAXN 200002
#define MAX(x,y) ( (x) > (y) ? (x) : (y) )
#define MIN(x,y) ( (x) < (y) ? (x) : (y) )
int buf1[MAXN];
int buf2[MAXN];
int buf3[MAXN];
int sa[MAXN];
int h[MAXN];
int * rk;
char s[MAXN];
int
keq( int *v, int x, int y, int l ) {
return v[x] == v[y] && v[x + l] == v[y + l];
}
void
bd_sa( char *s, int n, int mv ) {
int * vi;
int * sv;
int * lv;
int * t;
int v;
int cl;
int i, j;
vi = buf1;
sv = buf2;
lv = buf3;
for ( i = 0; i <= mv; i++ ) sv[i] = 0;
for ( i = 0; i <= n; i++ ) sv[ vi[i] = s[i] ]++;
for ( i = 1; i <= mv; i++ ) sv[i] += sv[i - 1];
for ( i = n; i >= 0; i-- ) sa[ --sv[ vi[i] ] ] = i;
for ( cl = 1, v = 0; v <= n; cl <<= 1, mv = v ) {
for ( j = 0, i = n - cl + 1; i <= n; i++ ) lv[j++] = i;
for ( i = 0; i <= n; i++ ) if ( sa[i] >= cl ) lv[j++] = sa[i] - cl;
for ( i = 0; i <= mv; i++ ) sv[i] = 0;
for ( i = 0; i <= n; i++ ) sv[ vi[ lv[i] ] ]++;
for ( i = 1; i <= mv; i++ ) sv[i] += sv[i - 1];
for ( i = n; i >= 0; i-- ) sa[ --sv[ vi[ lv[i] ] ] ] = lv[i];
for ( t = vi, vi = lv, lv = t, vi[ sa[0] ] = 0, v = 1, i = 1; i <= n; i++ )
vi[ sa[i] ] = keq( lv, sa[i - 1], sa[i], cl ) ? v - 1 : v++;
}
rk = vi;
}
void
bd_h( char *s, int n ) {
int i, j;
int cl;
for ( cl = 0, i = 0; i < n; h[ rk[i++] ] = cl )
for ( cl ? --cl : 0, j = sa[ rk[i] - 1 ]; s[i + cl] == s[j + cl]; cl++ );
}
int
main() {
int len;//字符串长
int n;//合并后的长度
int ml;//maximum length,最长公共子串长度
int ll;//lft link,左链接临时变量
int lft, rht;//最长公共子串的左右区间
int i;
scanf("%d", &len);
scanf("%s", s);
s[len] = '#';
scanf("%s", s + len + 1);
n = ( len << 1 ) + 1;
bd_sa( s, n, CHN );
bd_h( s, n );
for ( ml = 0, i = 1; i <= n; i++ )
if ( h[i] > ml )
if ( ( ll = MIN( sa[i - 1], sa[i] ) ) < len && MAX( sa[i - 1], sa[i] ) > len ) {
ml = h[i];
lft = ll;//更新左边界
rht = lft + ml;//更新右边界
}
//直接输出,不要逐个输出
s[rht] = '\0';
puts(s + lft);
return 0;
}
无注释代码:
#pragma GCC optimize("O2")
#include <stdio.h>
#define CHN 'Z'
#define MAXN 200002
#define MAX(x,y) ( (x) > (y) ? (x) : (y) )
#define MIN(x,y) ( (x) < (y) ? (x) : (y) )
int buf1[MAXN];
int buf2[MAXN];
int buf3[MAXN];
int sa[MAXN];
int h[MAXN];
int * rk;
char s[MAXN];
int
keq( int *v, int x, int y, int l ) {
return v[x] == v[y] && v[x + l] == v[y + l];
}
void
bd_sa( char *s, int n, int mv ) {
int * vi;
int * sv;
int * lv;
int * t;
int v;
int cl;
int i, j;
vi = buf1;
sv = buf2;
lv = buf3;
for ( i = 0; i <= mv; i++ ) sv[i] = 0;
for ( i = 0; i <= n; i++ ) sv[ vi[i] = s[i] ]++;
for ( i = 1; i <= mv; i++ ) sv[i] += sv[i - 1];
for ( i = n; i >= 0; i-- ) sa[ --sv[ vi[i] ] ] = i;
for ( cl = 1, v = 0; v <= n; cl <<= 1, mv = v ) {
for ( j = 0, i = n - cl + 1; i <= n; i++ ) lv[j++] = i;
for ( i = 0; i <= n; i++ ) if ( sa[i] >= cl ) lv[j++] = sa[i] - cl;
for ( i = 0; i <= mv; i++ ) sv[i] = 0;
for ( i = 0; i <= n; i++ ) sv[ vi[ lv[i] ] ]++;
for ( i = 1; i <= mv; i++ ) sv[i] += sv[i - 1];
for ( i = n; i >= 0; i-- ) sa[ --sv[ vi[ lv[i] ] ] ] = lv[i];
for ( t = vi, vi = lv, lv = t, vi[ sa[0] ] = 0, v = 1, i = 1; i <= n; i++ )
vi[ sa[i] ] = keq( lv, sa[i - 1], sa[i], cl ) ? v - 1 : v++;
}
rk = vi;
}
void
bd_h( char *s, int n ) {
int i, j;
int cl;
for ( cl = 0, i = 0; i < n; h[ rk[i++] ] = cl )
for ( cl ? --cl : 0, j = sa[ rk[i] - 1 ]; s[i + cl] == s[j + cl]; cl++ );
}
int
main() {
int len;
int n;
int ml;
int ll;
int lft, rht;
int i;
scanf("%d", &len);
scanf("%s", s);
s[len] = '#';
scanf("%s", s + len + 1);
n = ( len << 1 ) + 1;
bd_sa( s, n, CHN );
bd_h( s, n );
for ( ml = 0, i = 1; i <= n; i++ )
if ( h[i] > ml )
if ( ( ll = MIN( sa[i - 1], sa[i] ) ) < len && MAX( sa[i - 1], sa[i] ) > len ) {
ml = h[i];
lft = ll;
rht = lft + ml;
}
s[rht] = '\0';
puts(s + lft);
return 0;
}
单词解释:
Albania:阿尔巴尼亚,东欧国家
Albanian:阿尔巴尼亚人
bear with:vt, 忍受,宽容
democratic:adj, 民主的
presidential:adj, 总统的,首长的
politician:n, 政治家,政客
liberal:n, 自由主义者; adj, 自由主义的
conservative:n, 保守派; adj, 保守的
rival:n, 对手,竞争者
intention:n, 意图,目的
post:n, 岗位
compete:vt, 竞争,比赛
entertain:vt, 娱乐,款待
dirt:n, 污泥,污垢
cheer:n, 欢呼,愉快
approval:n, 认可,赞成,批准
occasion:n, 时机,场合
devote to:vt, 致力于,专注于
voter:n, 投票人
blame sb for sth:责备某人某事
opponent:n, 对手,反对派
corruption:n, 贪污,腐败
disrespect:n, 失礼,不敬
elder:n, 老人,长辈
terrorism:n, 恐怖主义
affiliation:n, 友好关系,联盟
socialist:n, 社会主义者; adj, 社会主义的
comrade:n, 同志(共产党的正式叫法)
fragment:n, 碎片,片段
identical:adj, 完全相同的