POJ 1743 字尾陣列

2022-07-19 17:27:19 字數 1753 閱讀 3272

求滿足下列要求的最長子串:

1.長度不小於5

2.出現兩次(子串整體加上某個值也算出現一次

3.兩次出現無重疊

難處理的是第二個要求:整體增加某個數也算出現一次

稍微思考一下便會得出:整體加上某個值後,相鄰數的差值是不變的

所以用乙個陣列r[i]儲存mus[i+1]與mus[i]的差值

這裡要注意將差值加上88,使差值始終為正以免在計算sa、rank的時候re,同時字符集大小也變成了88*2

二分答案的同時將字尾按大於mid height分組,滿足要求的子串肯定是同一組內的字尾的公共字首

用l、r記錄子串範圍,r-l則為兩個字尾起始位置距離,若r-l>mid則符合要求(不重疊)

這裡要注意的是:

1.sa對應的是差值的字尾,所以反饋到初始陣列的話,ans需要+1(5個數字只有4個差值)

2.計算height的時候傳入n-1,以免出現n=1的情況使得rank[0]-1=-1而出現re

#include"

cstdio

"#include

"queue

"#include

"cmath

"#include

"stack

"#include

"iostream

"#include

"algorithm

"#include

"cstring

"#include

"queue

"#include

"map

"#include

"set

"#include

"vector

"#define ll long long

#define mems(a,b) memset(a,b,sizeof(a))

#define ls pos<<1

#define rs pos<<1|1

using

namespace

std;

const

int maxe = 500050

;const

int maxn = 20005

;const

int inf = 0x3f3f3f3f

;int

sa[maxn];

intx[maxn],y[maxn],radix[maxn],trank[maxn];

intrank[maxn];

intmus[maxn],r[maxn];

intn;

void get_sa(int *r,int *sa,int n,int

m) }

for(i = 0; i < n; i ++) rank[sa[i]] =i;

//for(i=0;i}

intheight[maxn];

void get_height(int *r,int *sa,int

n)bool check(int

mid)

else l=r=sa[i];

}return

false;}

intmain()

else high=mid-1

; }

if(ans<4) ans=0

;

else ans++;

printf(

"%d\n

",ans);

}return0;

}

view code

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(字尾陣列)

給定乙個字串,求最長重複子串,這兩個子串不能重疊。演算法分析 這題比上一題稍複雜一點。先二分答案,把題目變成判定性問題 判斷是否 存在兩個長度為 k 的子串是相同的,且不重疊。解決這個問題的關鍵還是利用height 陣列。把排序後的字尾分成若干組,其中每組的字尾之間的 height 值都不小於 k。...