bzoj 3277 串 (廣義字尾自動機)

2021-07-25 14:43:31 字數 1332 閱讀 7164

time limit: 10 sec  

memory limit: 128 mb

submit: 357  

solved: 144 [

submit][

status][

discuss]

字串是oi界常考的問題。現在給定你n個字串,詢問每個字串有多少子串(不包括空串)是所有n個字串中至少k個字串的子串(注意包括本身)。

第一行兩個整數n,k。

接下來n行每行乙個字串。

輸出一行n個整數,第i個整數表示第i個字串的答案。

3 1abca

ab6 1 3

對於100%的資料,n,k,l<=100000

字尾陣列 [

submit][

status][

discuss]

題解:字尾自動機

這道題在預處理的時候與bzoj 2780是相同的。

我們要求每個字串有多少子串是所有n個字串中至少k個字串的子串,先不考慮k個字串的限制,該如何求解一共有多少子串呢?

我們記錄了從根到每個狀態最長的串的長度。l[i]-l[fa[i]]記錄的就是加入該點重新出現的子串的個數,但是我們這裡要算的是子串,這裡的子串是可以有相同的,所以我們這個點parent鏈上所有的節點的l[i]-l[fa[i]]的個數其實都是以該點為字尾的子串。

現在考慮k的限制,我們再上面的統計中,需要建立parent樹,然後將根節點到該點路徑上的值都累加到該點上。

那麼我們直接將size[i]l[i]-l[fa[i]]。

最後統計答案的時候,就將每個串中每個位置在字尾自動機中的對應節點的合法子串數相加即可。

#include#include#include#include#include#define n 200003

#define ll long long

using namespace std;

int n,m,np,nq,p,q,cnt,root,last,len,sz;

int ch[n][20],fa[n],size[n],l[n],nxt[n],a[n],now,pd[n],mark[n],v[n],pos[n];

int point[n],next[n],vi[n],tot,tt;

int head[n],nt[n];

ll c[n];

char s[n];

void add(int x,int y)

void addfa(int x,int y)

c[1]=0;

dfs(1);

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

}

BZOJ 3277 串 廣義字尾自動機

判斷乙個串是否在至少k個字串裡面的方法後3473一樣,每新增乙個新的字元就沿fail鏈更新。剩下的問題就只是剩下了,每增加乙個新的字元,共多出現了多少個新的字串,如果不要求重複,那麼很顯然就是len u len fail u 這裡重複的字串也需要加入答案所以只用沿fail鏈dfs一下,sum u f...

bzoj3277 串 廣義字尾自動機

廣義字尾自動機板子題 廣義字尾自動機的建圖方法大概就是在trie上按bfs序來建圖,這裡的last節點應該是trie上父親的last節點 然後這裡按題目要求記right為在至少k個串走過的方案,具體建法就是先把每個串跑一遍然後在parent樹上更新所有父親節點的答案,注意不要判重。然後掃一遍所有節點...

BZOJ3277 串 廣義字尾自動機

time limit 10 sec memory limit 128 mb submit 1196 solved 478 submit status discuss 字串是oi界常考的問題。現在給定你n個字串,詢問每個字串有多少子串 不包括空串 是所有n個字串中 至少k個字串的子串 注意包括本身 第...