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)=titi
+1...
ti+k
-1, 1≤
i≤i+k-1≤|
t|.given two strings a, b and one integer k, we define s, a set of triples (i, j, k):
s = .
you are to give the value of |s| for specific a, b and k.
input
the input file contains several blocks of data. for each block, the first line contains one integer k, followed by two lines containing strings a and b, respectively. the input file is ended by k=0.
1 ≤ |a|, |b| ≤ 105
1 ≤ k ≤ min
characters of a and b are all latin letters.
output
for each case, output an integer |s|.
sample input
2sample outputaababaa
abaabaa1xx
xx0
22source5
poj monthly--2007.10.06, wintokk
題意是求兩個字串長度》=k的公共子串有多少個。
先考慮怎麼求解公共子串的問題。公共子串可以用字尾陣列求,將兩個字串str1和str2合併為乙個字串,中間插入乙個不會出現的字元做分割。得到字尾陣列和高度陣列,有了高度陣列就可以求出任意兩個字尾的lcp最長公共字首值,lcp即為兩個字尾之間height[i]的最小值。
回到這個問題上,假如兩個分別屬於str1和str2的字尾lcp為x (x>k), 那麼就計數x-k+1個長度》=k的公共子串。那麼答案就是每個屬於str1和每個屬於str2的lcp-k+1求和。
直接列舉要n^2logn複雜度(單次查詢兩個字尾lcp用rmq--logn複雜度)。任意兩個字尾的lcp值取決於它們之間的最小值,直接列舉慢就慢在每兩個字尾都要找一遍它們之間的最小值。利用最小值這個關鍵點,假如列舉以第i個lcp值為最小值的區間[l,r],那麼ans+=(左邊屬於str1的字尾個數*右邊屬於str2+左邊屬於str2*右邊屬於str1)*(lcp-k+1)。而找到以某個值為最小值的區間用單調佇列左右掃一遍o(n)就可以得到。
#include #include #include #include #include using namespace std;
const int maxn=200005;
int t1[maxn], t2[maxn], c[maxn];
bool cmp(int *r, int a, int b, int l)
void da(int str, int sa, int rank, int height, int n, int m)
int k=0;
n--;
for(i=0; i<=n; i++) rank[sa[i]]=i;
for(i=0; iheight[i]) tail--;
if(tail+1!=head) lb[i]=que[tail]+1;
else lb[i]=1;
que[++tail]=i;
}head=0, tail=-1;
for(int i=n; i>=1; i--)
memset(sum, 0, sizeof(sum)); //字首和維護區間內屬於str1的字尾個數
for(int i=1; i<=n; i++){
if(sa[i]
POJ 3415 字尾陣列 單調棧
簡略題意 求兩個串長度不小於k的公共子串的個數。我喜歡這題!首先按height分組,隨後對於每個a字尾,看之前出現的b字尾與其的lcp,若其長度為 x 則對答案的貢獻為x k 1。暴力查詢n2 其實b字尾的排名越接近當前a字尾,兩者的lcp越高 想一想,為什麼,因此維護乙個單調棧,以及棧內元素貢獻總...
POJ 3415 字尾陣列
題意 給定2個串 a串和b串 求兩個串公共子串長度大於等於k的個數。思路 首先是兩個字串的問題。所以想用乙個 把兩個字串拼接起來。求字尾陣列。然後按照k把height陣列分組。大於等於k的為一組,然後就是統計每組的貢獻。對於每一組的貢獻即是組內所有a串的字尾和b串的字尾的lcp值,即為val.那麼v...
POJ 3415 字尾陣列 單調棧 並查集
題意 傳送門 poj 3415 題解子串是原串中連續的一段,也可以定義為字首的字尾或字尾的字首。統計分別屬於 a,b a,ba,b 的不小於 k kk 的子串個數,那麼將 a,b a,ba,b 用乙個不屬於這兩個串的字元拼接起來 避免拼接位置對結果產生影響 構造字尾陣列以及高度陣列 lcp i lc...