校內模擬 子串(SAM)(LCT)(主席樹)

2021-09-27 13:05:42 字數 2269 閱讀 8188

考慮怎麼算答案。

首先本質不同子串個數大概就是幾種做法,字尾陣列,字尾自動機,暴力

然後字尾自動機。。。眾所周知,並沒有區間字尾自動機這種扯淡的資料結構。

換乙個思路,我們並不直接統計,而是對於前面每乙個重複出現的字串,打上-1標記。

仔細想一想即可得到本題正解。

怎麼得到重複字串,顯然是sam跳fail鏈,每個點維護right集合最大值,更新之前先把前面的-1打上標記,對於每個右端點可持久化一下,主席樹標記永久化維護區間加區間求和。

發現right集合最大值相同的更新起來的是連續的,直接用lct維護最大值相同的鏈,那麼新加乙個點直接access,在access的同時在主席樹裡面修改即可。

由finger search 理論,複雜度只有乙個o(n

log⁡n)

o(n\log n)

o(nlogn)

最後實現注意一下字串邊界,lct稍微考慮一下可以不用寫cut。

其實就是在斷掉父親和它之間的實邊之後,將它splay,然後直接改父親指標,也就是子樹換父親(我真tm機智)。

**:

#include

#define ll long long

#define re register

#define cs const

namespace io

inline

char

peek()

inline

charga(

)template

<

typename t>

inline t get()

inline

intgi()

inline ll gl()

}using

namespace io;

using std::cerr;

using std::cout;

cs int n=

1e5+7;

int m;

namespace pst

inline

void

ins(

int&u,

int l,

int r,

int ql,

int qr,

int v)

int mid=l+r>>1;

if(ql<=mid)

ins(lc[u]

,l,mid,ql,qr,v);if

(midins(rc[u]

,mid+

1,r,ql,qr,v);}

inline ll query

(int u,

int l,

int r,

int ql,

int qr)

}int rt[n]

;namespace lct

inline

void

pushdown

(int u)

}inline

bool

isrt

(int u)

inline

bool

which

(int u)

inline

void

rotate

(int u)

inline

void

splay

(int u)

inline

void

access

(int u,

int id)

son[u][1

]=ch;

}pushtag

(ch,id);}

inline

intget

(int u)

inline

void

link

(int u,

int f)

}int nowl;

namespace sam

inline

void

push_back

(int c)}}

ll ans;

int n,m,op;

char s[n]

;inline

void

ins(

)inline

void

query()

#ifdef zxyoi

#undef zxyoi

#endif

signed

main()

}return0;

}

BJ模擬 String(SAM LCT 主席樹)

傳送門 題意 給字串 s s 支援 1.末尾加入字元。2.查詢 l r role presentation l,r l r 中出現兩次的最長字串。題解 好題。考慮離線做法 動態插入後面的字元,更新前面 l l 的答案。當我們插入乙個字元 r role presentation r r的時候,與前面的...

聯賽模擬測試5 序列 主席樹

對於每乙個位置,我們開一棵權值線段樹,記錄這個位置上的每乙個取值對答案的貢獻 對於每一次詢問,對它有貢獻的點是區間 l,r 中大於等於 x 的數 因此我們考慮差分,在 l 的位置 1 在 r 1 的位置 1 轉換到具體的點上,就是當點的座標恰好為 l 在 x 的位置 1 恰好為 r 1 在 x 的位...

校內模擬 層流 樹鏈剖分

給出一棵樹,給出n條邊,問這些邊兩兩之間是否滿足兩個條件之一 覆蓋對方或被對方覆蓋 沒有相交。如果都滿足輸出yes,否則輸出no。題解考場上第一眼就覺得是樹剖,畢竟前段時間天天見到這種型別的東西。做法有點差分的意思,在每條邊的兩個頂點異或上某個值,然後查詢這條邊上的異或和,如果合法異或和當然為0。但...