字尾自動機

2021-10-08 11:38:30 字數 1595 閱讀 7504

#include#include#includeusing namespace std;

const int n=1000000+10;

char s[n];

int len[2*n],tr[2*n][32],link[2*n],con=2,last=1;

void add(int c)}}

}int main()}}

return now;

}void bfs()//link圖的拓撲排序

串和串之間用特殊字元拼接,求和時按拓撲排序遞推,不能經過特殊字元的邊,也不能算包含特殊字元的字串

#include#include#include#includeusing namespace std;

typedef long long ll;

const int n=2e6+10;

const ll mod=1e9+7;

int len[2*n],link[2*n],tr[2*n][16],con=2,last=1,deg[2*n],road[2*n];

ll sum[2*n],ans=0;

char s[n];

void add(int c)

last=now;

if(!p)link[now]=1;

else}}

}void bfs()}}

}bool cmp(int a,int b)

int main()

tree[n*200];

int add(int c)}}

return now;

}void build(int l,int r,int &now,int x)//維護link樹的葉子節點

int change(int l,int r,int n1,int n2)//合併兩棵樹

int query(int l,int r,int now,int k)

void bfs()//link圖的拓撲排序

for(int i=1;i=0;--i)

if(tree[rt[now]].v#include#include#includeusing namespace std;

typedef long long ll;

const int n=1e5+10;

int len[2*n],link[2*n],tr[2*n][32],con=2,last=1,deg[2*n],ens[2*n],par[2*n][32],vis[2*n];

char s[2*n];

int add(int c)}}

return now;

}void bfs()//link圖的拓撲排序

l=2*l-1;

int ml=0,now=1;

ll ans=0;

memset(vis,0,sizeof(vis));

for(int i=0;i=k)

if(!vis[now])

}

}else

}printf("%lld\n",ans);

}return 0;

}

字尾自動機

基礎知識 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 罪...