題意:
給乙個模式串,然後給n個匹配串,問模式串裡有多少個子串是n個匹配串裡都不存在的
思路:
就是注意乙個性質就行了
假設當前節點的len==6,當前節點的pre節點len==2
這個節點接收的狀態就是以當前節點為最後乙個字元的字尾的長度是3~6裡
比如當前節點的最長字尾是abcabb(sam.len==6),pre節點是b(sam.len==2)
那麼當前節點的接收子串是abcabb,bcabb,cabb,abb
pre節點接收的狀態就是bb,b
所以當前節點的狀態包含pre節點
就是這個性質…
然後就比較簡單了
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
#define lowbit(x) (x&(-x))
typedef
long
long ll;
const
int maxn = 300005;
const
int inf=(1
<<28)-1;
struct sam_node
};class sam
void init()
void extend(char ch)
}last=np;
}void build(char* str)
int r[maxn*2],w[maxn];
//r[i]為topsort後 入度為0先入隊
void topsort()
void output()
}void add(char* str)
if(sam[p].son[id]!=-1)
dp[p]=max(dp[p],tmp);}}
ll solve()
return ans;
}}sam;
char str[maxn];
int main()
ll ans=sam.solve();
printf("case %d: %lld\n",++case,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 罪...