YbtOJ 532 往事之樹

2022-06-13 13:54:10 字數 1723 閱讀 2093

不難發現兩個串 \(r(x),r(y)\) 的 lcs 就是它們 lca 的深度。考慮列舉 lca,然後求子樹內所有字串的 lcp 最大值。

發現題目給出的是一棵 trie,我們可以直接離線構造廣義 sam。那麼此時樹上兩個點 \(x,y\) 的 lcp 長度就是他們在 parent 樹上的 lca 的 \(\text\)。

但是我們不能依次枚舉子樹內的兩個點,但是我們發現 parent 樹上兒子節點的 \(\text\) 一定大於它父親的 \(\text\),所以我們沒有必要求 \(o(n^2)\) 個點對的 lca,只需要把他們按照 parent 樹上 dfs 序相鄰的計算一下就可以了。

此時我們依然需要維護乙個資料結構支援維護子樹內的資訊,並且支援往父節點合併。考慮權值線段樹,線段樹乙個葉子 \([i,i]\) 表示 parent 樹上 dfs 序為 \(i\) 的點。如果這個點在當前子樹中就為 \(1\),否則為 \(0\)。

然後權值線段樹上維護區間 dfs 序相鄰的點的 lcp 最大值,以及區間最左最右的點。兩個區間 pushup 時可能產生的貢獻只有區間臨界點左右的一對點。可以 \(o(\log n)\) pushup(如果用 st 表預處理 lca 就可以做到 \(o(1)\) pushup,這樣總複雜度只有乙個 \(\log\))。

然後往上線段樹合併即可。

時間複雜度 \(o(n\log^2 n)\)。

#include using namespace std;

const int n=400010,lg=20,maxn=n*lg;

int n,ans,tot,a[n],dep[n],rt[n],last[n],head[n];

struct edge

e[n];

void add(int from,int to)

; head[from]=tot;

}struct sam

int ins(int last,int c)

}return np; }

void adde()

void dfs(int x)

}sam;

struct segtree

int update(int x,int l,int r,int k)

int mid=(l+r)>>1;

if (k<=mid) lc[x]=update(lc[x],l,mid,k);

else rc[x]=update(rc[x],mid+1,r,k);

pushup(x);

return x; }

int merge(int x,int y)

}seg;

void dfs1(int x,int fa)

void dfs2(int x)

rt[x]=seg.update(rt[x],1,2*n,sam.dfn[last[x]]);

ans=max(ans,seg.res[rt[x]]+dep[x]-1);

}int main()

dfs1(1,0);

sam.adde();

sam.tot=0; sam.dfs(1);

dfs2(1);

printf("%d",ans);

return 0;

}

上海往事之看房子

上海往事之看房子 2015年夏天,老婆趁孩子放暑假的機會,帶孩子一起來上海我所入住的酒店和我一起生活。那段時間,我所參與的akm專案已經於7月1日上線了,加上專案上線後執行比較穩定,所以事情不算太多,比較清閒。加上當時我們手上有點積蓄,所以我們利用週末的時間去上海及其周邊看了看房子,如果遇到合適的,...

上海往事之與Andy Tang小聚

andy tang 是我在ibm公司入職時候的同事,現在是筆者為數不多的好友之一。初識andy tang,還是十年前的時候。2007 年筆者入職成都ibm公司,加入當時在公司赫赫有名的聯想sap專案。當時聯想剛剛收購ibm pc部門不久,聯想公司就啟動了長達十年以上的直到今天尚未停止的sap系統實施...

虛擬桌面之往事如風 讀書篇

作為國內較早一批研究終端服務的技術人員,分享一下個人對這些技術的學習經歷。自2001 年的學生時代開始關注終端虛擬桌面技術以來,第一本讓我對終端服務有足夠認識的書,在學校圖書館裡發現了他,並且有相見恨晚的感覺,先後借了好幾次這本書。還記得這本書最後幾頁的遠端應用發布的案例,今天依然清晰記得。這本書我...