BZOJ 3879 SvT 虛樹 字尾樹

2022-04-06 20:18:02 字數 1466 閱讀 7041

傳送門

題意:多次詢問,給出一些字尾,求兩兩之間$lcp$之和

哈哈哈哈哈哈哈竟然$1a$了,剛才還在想如果寫不好這道題下節數學就不上了,看來是上天讓我上數學課啊

$suffix\ virtual\ tree$

沒有多次詢問就是那道差異了

多次詢問總次數$o(n)$,建出字尾樹每次建虛樹就行了

然後詢問給出的是字尾,用乙個$pos$對映到字尾樹上的點

然後$right$集合要在$dp$的時候遞推

貌似還有字尾陣列的做法跑的好快

#include #include 

#include

#include

#include

using

namespace

std;

typedef

long

long

ll;const

int n=1e6+5,inf=1e9;

inline

intread()

while(c>='

0'&&c<='9')

return x*f;

}int

n,q;

char

s[n];

struct

statet[n];

int sz=1,root=1,last=1

;int

pos[n];

void extend(int

c) }

last=np;

}struct

edgee[n];

intcnt,h[n];

inline

void ins(int u,int

v)int dfn[n],dfc,fa[n][21

],deep[n];

void dfs(intu)}

inline

int lca(int x,int

y)inline

bool cmp(int x,int y)

intst[n],key[n],a[n];

intd[n];

ll ans;

void dp(int

u) h[u]=0;}

void

virtree()

int x=a[i],f=lca(x,st[top]);

while(dfn[f]else ins(st[top-1],st[top]),top--;

}st[++top]=x;

}while(top>1) ins(st[top-1],st[top]),top--;

ans=0

; dp(st[

1]);

printf(

"%lld\n

",ans);

for(int i=1;i<=n;i++) key[a[i]]=0;}

intmain()

BZOJ3879 SvT(字尾自動機,虛樹)

bzoj 看著這個東西,詢問若干個字首兩兩之間的 lcp 顯然 lcp 就是 sam 構建出來的 parent 數上的 lca 所代表的長度。那麼這樣子就轉為了樹型 dp 然後發現是字首?把串轉過來就是字尾了。sum t 是 o n 級別的?顯然虛樹。那麼直接虛樹搞搞就好了。include incl...

bzoj3879 SvT 字尾陣列 RMQ

題目大意 給定乙個字串。每次詢問給定 t 個位置,求兩兩位置開頭的字尾的 lcp 之和。注釋 1 le length le 5 cdot 10 5 sum t le 3 cdot 10 6 想法 不難想到構建字尾陣列。進而我們的問題就轉化成了給定序列上一些位置求這些位置兩兩之間區間最小值的和。對 h...

BZOJ3879 SvT(字尾陣列 單調棧)

點此看題面 大致題意 給定乙個字串,每次詢問給出若干字尾,求兩兩之間的 lcp 之和。明明是想練字尾自動機的,結果看到這題一眼想到字尾陣列,而且一兩分鐘就推出了解法,因此最終默默地寫了字尾陣列。不過真的好坑啊,題目最下面寫了可能存在相同字尾,且相同字尾只計算一次答案。沒看到這句話的我白白浪費了半個小...