POJ 3415 字尾陣列

2022-08-31 03:54:08 字數 2037 閱讀 9066

題意:給定2個串[a串和b串],求兩個串公共子串長度大於等於k的個數。

思路:首先是兩個字串的問題。所以想用乙個'#'把兩個字串拼接起來。求字尾陣列。 然後按照k把height陣列分組。大於等於k的為一組,然後就是統計每組的貢獻。對於每一組的貢獻即是組內所有a串的字尾和b串的字尾的lcp值,即為val.那麼val對於答案的貢獻為(val-k+1)。如果我們暴力每組的ab串字尾的組合。時間複雜度是o(n^2).不能滿足要求。所以要用另外的辦法來優化計算。利用height陣列的性質,滿足單調不增的特點,所以我們可以用乙個單調棧來優化計算。 對於每個分組。我們分2種情況來計算。一:把b串的字尾放入單調棧。每列舉到乙個a串字尾就和單調棧的值進行計算貢獻。二:把a串的字尾放入單調棧。每列舉到乙個b串字尾就和單調棧的值進行計算貢獻。 對於如何維護這個單調棧:如果對於情況一,如果每遇到乙個a串字尾就和棧內所有的b字尾都計算一遍會退化到o(n^2).所以棧還要維護乙個字首貢獻值,這樣就可以把複雜度將為o(n)。       關於維護字首貢獻值是從這篇部落格學習到的。 該題也可以用字尾自動機來寫,而且好像比字尾陣列容易。

#define _crt_secure_no_deprecate#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

typedef

long

long

intll;

const

int maxn = 100000 * 2 + 10

;int cmp(int *r, int a, int b, int

l)int

wa[maxn], wb[maxn], wv[maxn], ws[maxn];

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

m)

for (i = 0; i < n; i++)

for (i = 1; i < m; i++)

for (i = n - 1; i >= 0; i--)

for (j = 1, p = 1; p2, m =p)

for (i = 0; i < n; i++)

}for (i = 0; i < n; i++)

for (i = 0; i < m; i++)

for (i = 0; i < n; i++)

for (i = 1; i < m; i++)

for (i = n - 1; i >= 0; i--)

for (t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i < n; i++)

}return;}

intrank[maxn], height[maxn], sa[maxn];

void calheight(int *r, int *sa, int

n)

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

return;}

intr[maxn], len, k, index;

char

str[maxn];

struct

nodes[maxn];

void

solve()

}top = 0

;

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

}printf(

"%lld\n

", ans);

}int

main()

r[index] = 1; r[len] = 0

; da(r, sa, len+1, 128

); calheight(r, sa, len);

solve();

}return0;

}

poj 3415 字尾陣列 單調佇列

common substrings time limit 5000ms memory limit 65536k total submissions 8106 accepted 2688 description a substring of a string t is defined as t i,k...

POJ 3415 字尾陣列 單調棧

簡略題意 求兩個串長度不小於k的公共子串的個數。我喜歡這題!首先按height分組,隨後對於每個a字尾,看之前出現的b字尾與其的lcp,若其長度為 x 則對答案的貢獻為x k 1。暴力查詢n2 其實b字尾的排名越接近當前a字尾,兩者的lcp越高 想一想,為什麼,因此維護乙個單調棧,以及棧內元素貢獻總...

POJ 3415 字尾陣列 單調棧 並查集

題意 傳送門 poj 3415 題解子串是原串中連續的一段,也可以定義為字首的字尾或字尾的字首。統計分別屬於 a,b a,ba,b 的不小於 k kk 的子串個數,那麼將 a,b a,ba,b 用乙個不屬於這兩個串的字元拼接起來 避免拼接位置對結果產生影響 構造字尾陣列以及高度陣列 lcp i lc...