hdu2328 字尾陣列 二分

2022-02-19 17:28:49 字數 1725 閱讀 8875

題意: 求 n 個串的字典序最小的最長公共子串

思路: 本題中單個字串長度不超過 200, 可以暴力列舉乙個字串的所有字首, 然後用kmp去匹配其他字串.

我這裡是用字尾陣列寫的. 類似

不過本題是有 n 個字串, 不能直接暴力判斷. 不難想到這裡可以直接二分答案長度, 不過 check 函式比較難想到, 具體看**

**:

1 #include 2 #include 3 #include 

4#define rank rank

5using

namespace

std;67

const

int maxn = 1e6 + 10;8

intsol;

9char

str[maxn];

10int sa[maxn], rank[maxn], height[maxn], sum[maxn], tp[maxn], vis[maxn], tag[(int)(4e3 + 10

)];11

12bool cmp(int *f, int x, int y, int

w)15

16void da(char *s, int n, int

m)27

for(int i = 0; i < m; i++) sum[i] = 0;28

for(int i = 0; i < n; i++) sum[rank[tp[i]]]++;

29for(int i = 1; i < m; i++) sum[i] += sum[i - 1

];30

for(int i = n - 1; i >= 0; i--) sa[--sum[rank[tp[i]]]] =tp[i];

31swap(rank, tp);

32 p = 1

;33 rank[sa[0]] = 0;34

for(int i = 1; i < n; i++)

37if(p >= n) break

;38 m =p;39}

40int k = 0

;41 n--;

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

43for(int i = 0; i < n; i++)49}

5051

bool check(int mid, int n, int

len)64}

65 }else70}

71return

false;72

}7374int main(void

)88 str[len] = 0

;89 da(str, len + 1, '

z' + 1

);90

for(int i = 1; i <= len; i++) vis[i] += vis[i - 1

];91

int l = 1, r =mx;

92while(l <=r)

97if(l - 1

<= 0

)101

for(int i = sol, j = 1; j <= l - 1; i++, j++)

104 puts(""

);105

}106

return0;

107 }

view code

字尾陣列 二分 hdu 5008

大致題意 給出乙個長度小於100000的字串,求字串中字典序排在第k位的子串。大致思路 聯動ural1590 這裡有乙個字尾陣列的基本規律,每個字尾去掉重複的字首之後留下的就是所有的子串。eg字串 aabb 排列成字尾陣列之後,代表height計算出的和sa i 1 相同的部分 sa 1 0 aab...

1402 字尾陣列 (hash 二分)

描述 字尾陣列 sa 是一種重要的資料結構,通常使用倍增或者dc3演算法實現,這超出了我們的討論範圍。在本題中,我們希望使用快排 hash與二分實現乙個簡單的 o n log 2 n 的字尾陣列求法。詳細地說,給定乙個長度為 n 的字串s 下標 0 n 1 我們可以用整數 k 0 k 輸入格式 乙個...

poj1743(字尾陣列 二分)

不可重疊最長重複子串 字尾陣列後,二分最長長度,在維護長度不小於mid時,判斷是否有兩個位置之間的差 mid,表示不重疊,由此更新l,r 方法 字串處理常用二分 字尾陣列常用分組 分組的本質就是這個組均包含長度為mid的子串,就是這個組的長度為mid的字首都相同 include include in...