POJ 1743(字尾陣列)

2021-10-04 15:41:48 字數 1729 閱讀 6332

給定乙個字串,求最長重複子串,這兩個子串不能重疊。

演算法分析:

這題比上一題稍複雜一點。先二分答案,把題目變成判定性問題:判斷是否

存在兩個長度為 k 的子串是相同的,且不重疊。解決這個問題的關鍵還是利用height 陣列。把排序後的字尾分成若干組,其中每組的字尾之間的 height 值都不小於 k。例如,字串為「aabaaaab」,當 k=2 時,字尾分成了 4 組。

容易看出,有希望成為最長公共字首不小於 k 的兩個字尾一定在同一組。然

後對於每組字尾,只須判斷每個字尾的 sa 值的最大值和最小值之差是否不小於k。如果有一組滿足,則說明存在,否則不存在。整個做法的時間複雜度為

o(nlogn)。本題中利用 height 值對字尾進行分組的方法很常用,請讀者認真體會。

注意:這道題和例題不一樣的點在於只要是兩個序列的差值相等都算相同的序列。要對原始序列初始化。cal[i]=cal[i]-cal[i-1];結果可能為負,可以整體加乙個數。長度變為 4;

但要給cal[1]賦乙個和其他所有數都不一樣的值。

例如: 2 3 4 5 7 8 9 10 15 20

答案應該是4,算出來是5。

#include

#include

#include

#include

#define f(x) ((x) / 3 + ((x) % 3 == 1 ? 0 : tb))

#define g(x) ((x) < tb ? (x) * 3 + 1 : ((x) - tb) * 3 + 2)

#define ll long long

using

namespace std;

const

int n =3*

(1e5+5

);int wa[n]

, wb[n]

, wss[n]

, wv[n]

, sa[n]

;int rak[n]

, height[n]

, cal[n]

,n;char s[n]

,ans[n]

,s1[n]

;int cnt[n]

;intc0(

int*r,

int a,

int b)

intc12

(int k,

int*r,

int a,

int b)

void

rsort

(int

*r,int

*a,int

*b,int n,

int m)

void

dc3(

int*r,

int*sa,

int n,

int m)

void

calheight

(int

*r,int

*sa,

int n)

bool

check

(int k)

else}if

(maxx-minn>=k)

return1;

return0;

}int

main()

if(l==3)

printf

("0\n");

else

printf

("%d\n"

,l+1);

}}

poj 1743 字尾陣列

字尾陣列,求不可重疊最長重複字串。include include include include include include define maxd 21000 using namespace std int r maxd rank maxd height maxd int sa maxd wa...

POJ 1743 字尾陣列

這裡有一篇 總結了很多字尾陣列的用法,是 字尾陣列 處理字串的有力工具 羅穗騫 裡面又很多關於這個字尾陣列的具體用法,其中就包括這個不可重疊最長重複子串 這個題的意思就是求解不可重疊最長重複子串,但是這裡有乙個問題,他的串中也可以是相似的 每個數之間的差值相同的 那麼我們就可以利用這個差相同的性質,...

POJ 1743 字尾陣列

求滿足下列要求的最長子串 1.長度不小於5 2.出現兩次 子串整體加上某個值也算出現一次 3.兩次出現無重疊 難處理的是第二個要求 整體增加某個數也算出現一次 稍微思考一下便會得出 整體加上某個值後,相鄰數的差值是不變的 所以用乙個陣列r i 儲存mus i 1 與mus i 的差值 這裡要注意將差...