bzoj3238 差異 字尾樹

2022-09-22 00:30:13 字數 839 閱讀 3938

題目大意:給你乙個字串$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 ...