P3975 (字尾自動機sort)

2022-05-01 01:36:12 字數 1020 閱讀 6480

求出所有字串的第k大子串

有兩種,第一種對於出現在不同位置的相同子串算作乙個子串

第二種,對於不同位置的子串算作是不相同子串

$1\leq |s| \leq5000 00$

對於第一種計算,endpos算作1,對於第二種,endpos是狀態出現的次數

對於當前狀態字首出現的次數為endpos+子狀態的出現次數

sam的拓撲序可以根據maxlen來排,maxlen越大,拓撲序肯定越小,無論是slink,還是trans邊,都是短的maxlen鏈結長的maxlen

用桶排序實現$o(n)$為它們排序

#includeusing namespace std;

const int n=1e6+10;

typedef long long ll;

char s[n/2];

char ans[n/2];

int fla,k,top;

struct suffixautomation

inline void ins(int c,int pos)

//然後順著parent樹的路徑向上找

if(p==0)int q=mp[p][c];//case1

if(len[p]+1==len[q])//case2

len[++ct]=len[p]+1;//case 3

for(int i=1;i<=26;i++)

fa[ct]=fa[q];fa[q]=ct;fa[ed]=ct;

for(int i=p;mp[i][c]==q;i=fa[i])

}void solve()

for(int i=ct;i>=1;i--)

int now=1;

while(1)else

if(k<=siz[now])break;

else k-=siz[now];

}ans[++top]=0;

printf("%s\n",ans+1);

}}sam;

int main()

字尾自動機

基礎知識 step i 表示的是字串i在原字串中的位置。pareint i 表示root到parent i 的子串是root到i的最長字尾。字尾自動機遍歷可以得到原字串的所有子串。特殊技巧 一 字尾自動機的不同子串數有兩種求法 1.ans step i step parent i 1 i cnt 2...

字尾自動機

常用於處理字串問題,可以高效解決許多字串問題。有點像將乙個字串的所有字尾都建在乙個ac自動機上,但不同的是字尾自動機的節點數最多為2 n,因為它只記錄需要記錄的點,一些沒有記錄東西的點可以視為與下面有價值的節點並在一起,這樣大大降低了時間複雜度和空間複雜度。對於每乙個節點記錄它的後面加上每個字元後字...

字尾自動機

基礎學習 簡潔明瞭的講解 總狀態數不超過2n 12n 1 2n 1 包括初始狀態 統計每個end po sendpos endpos 等價類出現位置數量時,要按長度從長到短的計算cnt cntcn t。那為什麼一定要從長到短呢?比如回文自動機就直接是按照節點編號從大到小計算cnt cntcn t 罪...