哈哈這道題自己yy出來了很開心(不過ozy大神告訴我與lca有關)。最長公共字首稍微想想都覺得很難搞,畢竟是字尾自動機,所以把原字串反過來建,然後變成了求最長公共字尾。對於兩個字尾,若他們在字尾自動機上對應的節點分別為
x x
和y' role="presentation" style="position: relative;">y
y,那麼他們的最長公共字尾長度就是mx
[lca
(x,y
)]m x[
lca(
x,y)
](這裡的lca指的是parent樹上的),這個也很好懂,因為公共,所以ri
ght rig
ht集合肯定一樣,所以就是lca,然後最長,那就是最長長度了。然後再求出每個節點是多少對字尾對應的點的lca即可,這個隨便搞,我用的是容斥。
#include
using
namespace
std;
#define ll long long
#define pa pair
const
int maxn=1000010;
const
int inf=2147483647;
int tot=1,last=1;
int mx[maxn],par[maxn],son[maxn][26];
ll f[maxn],ans=0;
void extend(int x)
}last=np;
}char s[maxn];
struct edgee[maxn];
int last[maxn],len=0;
void ins(int x,int y)
void dfs(int x)
if(!flag)
}int main()
BZOJ3238 AHOI2013 差異 題解
參考 第一道接觸字尾樹的題,然而不想講這個東西。我們只需要知道將串倒著建字尾自動機parent樹就是字尾樹即可。然後兩個字尾的lcp就是他們的lca的len。設點u,則過點u的字尾就有su子樹的size和個,所以能配出size u size u 1 2個對,這條路徑的長度貢獻為 tr u l tr ...
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 ...