題意: 求 n 個串的字典序最小的最長公共子串
思路: 本題中單個字串長度不超過 200, 可以暴力列舉乙個字串的所有字首, 然後用kmp去匹配其他字串.
我這裡是用字尾陣列寫的. 類似
不過本題是有 n 個字串, 不能直接暴力判斷. 不難想到這裡可以直接二分答案長度, 不過 check 函式比較難想到, 具體看**
**:
1 #include 2 #include 3 #includeview code4#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 }
字尾陣列 二分 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...