給你乙個長度為$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...