标签:++ trie class set empty std space ems ==
老经典题了
#include<bits/stdc++.h> using namespace std; #define N 105 #define ll long long #define mod 1000000007 ll n,m; char buf[N],s[N]; struct Matrix{ ll a[N][N]; Matrix(){memset(a,0,sizeof a);} }A; struct Trie{ int nxt[N][26],fail[N],end[N],L,root; int newnode(){ memset(nxt[L],-1,sizeof nxt[L]); end[L]=0; return L++; } void init(){ L=0; root=newnode(); } void insert(char s[]){ int len=strlen(s); int now=root; for(int i=0;i<len;i++){ if(nxt[now][s[i]-‘a‘]==-1) nxt[now][s[i]-‘a‘]=newnode(); now=nxt[now][s[i]-‘a‘]; } end[now]++; } void build(){ queue<int>Q; fail[root]=root; for(int i=0;i<26;i++) if(nxt[root][i]==-1) nxt[root][i]=root; else { fail[nxt[root][i]]=root; Q.push(nxt[root][i]); } while(!Q.empty()){ int now=Q.front();Q.pop(); if(end[fail[now]])end[now]=1; for(int i=0;i<26;i++){ if(nxt[now][i]==-1) nxt[now][i]=nxt[fail[now]][i]; else { fail[nxt[now][i]]=nxt[fail[now]][i]; Q.push(nxt[now][i]); } } } } void buildMrx(){ for(int i=0;i<L;i++) for(int j=0;j<26;j++) if(!end[i] && !end[nxt[i][j]]) A.a[i][nxt[i][j]]++; } }ac; void Mul(Matrix &A,Matrix &B){ Matrix res; for(int i=0;i<ac.L;i++) for(int j=0;j<ac.L;j++) for(int k=0;k<ac.L;k++) res.a[i][j]=(res.a[i][j]+A.a[i][k]*B.a[k][j])%mod; for(int i=0;i<ac.L;i++) for(int j=0;j<ac.L;j++) A.a[i][j]=res.a[i][j]; } Matrix Matrix_Pow(Matrix A,ll b){ Matrix res; for(int i=0;i<ac.L;i++) res.a[i][i]=1; while(b){ if(b%2)Mul(res,A); b>>=1;Mul(A,A); } return res; } int main(){ cin>>n>>m; ac.init(); for(int i=1;i<=m;i++){ int len;cin>>len>>buf; ac.insert(buf); } ac.build(); ac.buildMrx(); A=Matrix_Pow(A,n); ll ans=0; for(int i=0;i<ac.L;i++) ans=(ans+A.a[0][i])%mod; cout<<ans<<‘\n‘; }
【经典】ac自动机+矩阵快速幂——求长为n的不包含某些串的所有串个数 icpc cerc 2019
标签:++ trie class set empty std space ems ==
原文地址:https://www.cnblogs.com/zsben991126/p/12904662.html