模板 字尾自動機 SAM SAM解法

2022-09-02 01:39:09 字數 956 閱讀 3437

雖說是模板但也不是純粹板子!

sam應用1:求乙個子串的出現次數(相當於字串匹配)。

因為同乙個 \(\text\) 類中所有東西的結束集合都是相同的,故它們在母串中的出現次數也是相同的。因此,在該類中就應該貪心地選擇最長的串,也即 \(\text\)。

那麼我們如何求出乙個 \(\text\) 類中所有東西的出現次數呢?考慮parent tree。

parent tree的實質是往乙個集合中的串的開頭新增新字元的過程。於是,我們考慮dp。設 \(f_i\) 表示集合 \(i\) 中所有串的出現次數。則 \(f_i=1+\sum\limits_i\text}f_j\)。其中,那個 \(1\) 是指不加任何數的串本身。

時間複雜度 \(o(n|\sigma|)\)。

**:

#includeusing namespace std;

typedef long long ll;

const int n=1001000;

struct suffix_automatont[n<<1];//a sam has 2n nodes!!!

int f[n<<1];

int cnt=1;

int add(int x,int c)

int y=t[x].ch[c];

if(t[y].len==t[x].len+1)

int yy=++cnt;t[yy]=t[y];

t[yy].len=t[x].len+1;

t[y].fa=t[xx].fa=yy;

for(;x&&t[x].ch[c]==y;x=t[x].fa)t[x].ch[c]=yy;

return xx;

}int n;

char s[n];

vectorv[n<<1];

void dfs(int x)

ll res;

int main()

模板 字尾自動機 SAM SA解法

俗話說的好,模板題怎麼能用模板水過去呢 我們考慮用建出 ht 陣列,然後用單調棧求出每個 ht 最多能向左向右延伸多遠 vi.ahoi2013 差異 然後直接一邊掃過求 max 即可。複雜度 o n 假如你用dc3的話。但是用倍增實際跑起來也真的超快!includeusing namespace s...

字尾自動機模板

include include define maxc 28 using namespace std const int maxn 1e6 5 const int mod 1e9 7 typedef long long ll int len maxn 2 最長子串的長度 該節點字串數量 len x ...

模板 字尾自動機

求子串的出現次數。用類似拓撲排序的思想,從沒有出度的節點開始把他的cnt加在他的字尾連線上。include using namespace std typedef long long ll struct node void copynewnode const int l,const node n c...