題目大意:給你乙個字串$s$,設$s_i$是串$s$第$i$長的字尾,求:
$\sum\limits_^ \sum\limits_^ |s_i|+|s_j|-2\times lcp(s_i,s_j)$
其中$lcp(x,y)$表示字串$x$和字串$y$的最長公共字首
資料範圍:$|s|≤500000$
最近發現字尾樹和$sam$沒學好,找一點題來做一做
一道字尾樹的板題,我們用$sam$建出字尾樹後,直接$dfs$遍歷,通過$siz$更新$ans$即可,詳情見**
時間複雜度:$o(|s|)$
1 #include2#define m 1000005
3#define l long long
4using
namespace
std;56
char s[m]=;78
struct edgee[m]=; int head[m]=,use=0;9
void add(int x,int y,int z)
10 l siz[m]=,hh[m]=,n,ans=0;11
12namespace
sam28}29
}30void
build()
33};
3435
void dfs(int x,int
dep)
42 ans-=(siz[x]*siz[x]-sumsq)*dep;
43 ans-=hh[x]*dep*siz[x]*2
;44 siz[x]+=hh[x];45}
4647
main()
BZOJ3238 差異(字尾自動機)
bzoj 前面的東西直接暴力算就行了 其實沒必要算的正正好 為了方便的後面的計算 我們不考慮i,j 的順序問題 也就是先求出 n i 1 nj 1 i j len i 然後對於每個字尾樹上的節點,減去一下貢獻 也就是siz e i si ze i 1 le n i len i.p aren t 這樣...
BZOJ3238 差異(字尾自動機)
bzoj 前面的東西直接暴力算就行了 其實沒必要算的正正好 為了方便的後面的計算 我們不考慮 i,j 的順序問題 也就是先求出 sum n sum n i neq j len i 然後對於每個字尾樹上的節點,減去一下貢獻 也就是 size i size i 1 len i len i.parent ...
bzoj3238 差異(字尾陣列 單調棧)
顯然我們可以先把len ti len tj 的值先算出來,再把lcp減去。所有len ti len tj 的值為n n 1 n 1 2,這個隨便在紙上畫一畫就可以算出來的。接下來問題就是如何把lcp減去。我們先用字尾陣列把height求出來,當有一段區間l r,height i 為height l ...