求滿足下列要求的最長子串:
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"view codecstdio
"#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;
}
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。...