[題目鏈結]
[演算法]
首先 , 子串是字尾的字首
考慮拼接兩個字串 , 中間用不可見字元隔開 , 求出該字串的字尾陣列
那麼字首相同的字尾一定排名一定接近
而我們又知道lcp(i , j) = min
維護乙個單調遞增的字尾陣列即可
時間複雜度 : o(nlogn)(n = |a| + |b|)
[**]
#includeusingnamespace
std;
#define n 400010
const
int alpha = 26
;typedef
long
long
ll;typedef
long
double
ld;typedef unsigned
long
long
ull;
struct
info
;int
n , m , len;
intheight[n] , rk[n] , sa[n];
char
s[n] , s1[n] , s2[n];
template
inline void chkmin(t &x , t y)
template
inline void chkmax(t &x , t y)
template
inline void read(t &x)
inline
void
build_sa() }
inline
void
get_height()
}inline
void merge(info &x , info y);}
inline ll calc()
;
while (top > 0 && height[i] <=s[top].height)
s[++top] =tmp;
va += 1ll * s[top].height *s[top].cnta;
vb += 1ll * s[top].height *s[top].cntb;
if (sa[i] < n + 1) ret +=vb;
else ret +=va;
}
return
ret;
}int
main()
HAOI2016 找相同字元
給定兩個字串,求出在兩個字串中各取出乙個子串使得這兩個子串相同的方案數。兩個方案不同當且僅當這兩個子串中有乙個位置不同。兩行,兩個字串s1,s2,長度分別為n1,n2。1 n1,n2 200000,字串中只有小寫字母 題解 s1 s2拼起來。求height 要求 i j lcp rk i rk j ...
HAOI2016 找相同字元
其實這道題跟 ahoi2013 差異很像 其實這個問題的本質就是讓你算所有字尾的 lcp 長度之和,但是得來自兩個不同的字串 先把兩個字串拼起來做一遍 sa 由於我們多算了來自於同乙個串內的情況 於是在分別對這兩個串建 sa 減掉這兩次算出來的答案 現在的問題轉化為求出 height 陣列所有子區間...
HAOI2016 找相同字元 SAM
給乙個串建立sam,另乙個在sam上跑匹配,同時計算當前匹配串的所有字尾所產生的的貢獻。由於sam上乙個節點可能不包含所有字尾,要把fat he rfather father 的貢獻下放到son sonso n。詳情見 include include include include include ...