bzoj 3998 (字尾自動機)

2022-07-13 09:57:06 字數 1113 閱讀 1312

給你乙個長度為$n$的字串$str$和乙個數$k$,現在有兩個詢問:

1. $op=0$:不同位置的相同子串算作乙個,求字典序第$k$小子串

2. $op=1$:不同位置的相同子串算作多個,求字典序第$k$小子串

因為字尾自動機能夠包含所有的子串,因此我們考慮在字尾自動機上貪心的跳轉。

我們設字尾自動機上第$i$號結點所包含的字串的個數為$num[i]$,不難發現當前結點$i$的後繼們一共會包含$\sum_^\sum_^ num[st]$個字元。我們設它為$siz[i]$。

當我們在字尾自動機上進行跳轉時,如果當前位於的結點$i$的$num[st]+siz[i]而又因為本題有兩種操作,故需要分兩種情況討論。

對於$op=1$而言,因為不同位置子串算多個,則這個就等價於在每乙個結點的對整體的貢獻為$|endpos(i)|$

而對於$op=0$的情況,這就等價於在同乙個$endpos$下,答案只能貢獻$1$,即對於每乙個結點$i$而言,$num[i]=1$

最後我們只需要用拓撲排序求一下$endpos$的大小,以及用字尾和維護一下$siz$,最後統計答案即可。

(ps:對於op=0的情況,這題就等價於spoj sublexspoj~sublexsp

ojsu

blex

。)

#include

#define maxn 1000005

using

namespace std;

char str[maxn]

;struct sam

void

init

(char

*s)}

void

insert

(int c)}}

void

build

(int op)

else

} num[1]

=0;for

(int i = cnt; i >=

1; i--)}

}void

dfs(

int x,

int k)

k -= siz[tmp];}

}} sam;

intmain()

bzoj3998 字尾自動機

對於乙個給定長度為n的字串,求它的第k小子串是什麼。第一行是乙個僅由小寫英文本母構成的字串s 第二行為兩個整數t和k,t為0則表示不同位置的相同子串算作乙個。t 1則表示不同位置的相同子串算作多個。k的意義如題所述。輸出僅一行,為乙個數字串,為第k小的子串。如果子串數目不足k個,則輸出 1 aabc...

BZOJ3998 弦論 字尾自動機

題意 給定乙個長度為n的字串,求他的第k小子串是什麼。分析t 0的時候,這個題跟spoj sublex的做法一樣,當t 1的時候,不同位置的子串算多個,那麼初始化的時候d u cnt u 沒走乙個字元不是k 1而是k cnt u 1 include 2 include 3 include 4 inc...

bzoj3998 弦論 字尾自動機

對於乙個給定長度為n的字串,求它的第k小子串是什麼。第一行是乙個僅由小寫英文本母構成的字串s 第二行為兩個整數t和k,t為0則表示不同位置的相同子串算作乙個。t 1則表示不同位置的相同子串算作多個。k的意義如題所述。輸出僅一行,為乙個數字串,為第k小的子串。如果子串數目不足k個,則輸出 1 aabc...