要找乙個字串,使得它的長度盡可能的大,而且對於每個字串,它在字串或者它的翻轉串的其中乙個串**現過。
只要輸出最長的長度即可。
這道題我們考慮用 sa 加二分來做,雖然有很多解法。
首先,你把每個字串和他們的翻轉串拼接到乙個字串中,然後中間用互不相同的字元隔開。
然後跑 sa,得出 sai
sa_i
sai
。然後想到最長公共子串,我們會想到求 height 陣列。
那你如果要二分答案,你就要找到乙個區間,使得它包含了每個字串的,然後它 height 值裡面的最小值還要大於你二分的答案。
那這個你掃一遍過去找到每個區間來看行不行就可以了。
#include
#include
#include
#include
using
namespace std;
int n, m, t, t;
int p, tmp, sn, c[
100001
], height[
100001
], str[
100001];
int sa[
100001
], rak[
100001
], tp[
100001
], tax[
100001];
char s[
100001];
queue <
int> q;
bool in[
100001];
void
csh(
)void
paixu()
voidsa(
) m =
1000
;paixu()
;for
(int w =
1; w < n; w <<=1)
}void
get_height()
}bool
check
(int mid)if(
!in[str[sa[i -1]
]])}
else
if(q.
size()
== t)
return1;
return0;
}void
work()
int lef =
0, rig =
100, re;
while
(lef <= rig)
else rig = mid -1;
}printf
("%d\n"
, re);}
intmain()
c[++n]
=++tmp;
//中間用互不相同的字元隔開
str[n]
= ii;
for(
int i = sn; i >=
1; i--
) c[
++n]
=++tmp;
//中間用互不相同的字元隔開str[n] = ii;}sa
();//跑 sa
get_height()
;//得出 height 陣列
work()
;//二分答案
}return0;
}
ybt1265 最長公共子串行
時空限制 1000ms 64mb 乙個給定序列的子串行是在該序列中刪去若干元素後得到的序列。確切地說,若給定序列x m 則另一串行z k 是x的子串行是指存在乙個嚴格遞增的下標序列k 使得對於所有j 1,2,k有 xi j zj 例如,序列z 是序列x 的子串行,相應的遞增下標序列為 2,3,5,7...
最長公共子串行 最長公共子串
1 最長公共子串行 採用動態規劃的思想,用乙個陣列dp i j 記錄a字串中i 1位置到b字串中j 1位置的最長公共子串行,若a i 1 b j 1 那麼dp i j dp i 1 j 1 1,若不相同,那麼dp i j 就是dp i 1 j 和dp i j 1 中的較大者。class lcs el...
最長公共子串行 最長公共子串
1.區別 找兩個字串的最長公共子串,這個子串要求在原字串中是連續的。而最長公共子串行則並不要求連續。2 最長公共子串 其實這是乙個序貫決策問題,可以用動態規劃來求解。我們採用乙個二維矩陣來記錄中間的結果。這個二維矩陣怎麼構造呢?直接舉個例子吧 bab 和 caba 當然我們現在一眼就可以看出來最長公...