[JSOI2007]文本生成器 (AC自动机)
套路题,经典dp枚举当前在哪个节点
#include<bits/stdc++.h> #define rep(i,x,n) for(int i=x;i<=n;i++) using namespace std; typedef long long ll; typedef pair<int,ll> pll; const int N=1e5+10; string s; struct node{ int cnt; node *nxt[27]; node *fail; }*rt; int num,idx; node pool[N]; int val[N]; int f[105][6100][2]; void insert(string s,int x){ node *p=rt; int i; for(i=0;i<s.size();i++){ int sign=s[i]-'A'; if(p->nxt[sign]==NULL){ p->nxt[sign]=pool+(++idx); p->nxt[sign]->cnt=++num; } p=p->nxt[sign]; if(i==(int)s.size()-1){ val[p->cnt]=x; } } } void build(){ int i; queue<node *> q; rt->fail=rt; for(i=0;i<26;i++){ if(rt->nxt[i]){ rt->nxt[i]->fail=rt; q.push(rt->nxt[i]); } else{ rt->nxt[i]=rt; rt->nxt[i]->fail=rt; } } while(q.size()){ auto t=q.front(); q.pop(); for(i=0;i<26;i++){ if(t->nxt[i]){ t->nxt[i]->fail=t->fail->nxt[i]; q.push(t->nxt[i]); } else{ t->nxt[i]=t->fail->nxt[i]; } val[t->cnt]+=val[t->fail->cnt]; } } } int main(){ ios::sync_with_stdio(false); int n,m; cin>>n>>m; int i; rt=pool; rt->cnt=0; for(i=1;i<=n;i++){ cin>>s; insert(s,1); } build(); int j,k; memset(f,0,sizeof f); f[0][0][0]=1; for(i=1;i<=m;i++){ for(j=0;j<=num;j++){ for(k=0;k<26;k++){ int id=(pool+j)->nxt[k]->cnt; if(val[id]){ f[i][id][1]=(f[i][id][1]+f[i-1][j][0]+f[i-1][j][1])%10007; } else{ f[i][id][0]=(f[i][id][0]+f[i-1][j][0])%10007; f[i][id][1]=(f[i][id][1]+f[i-1][j][1])%10007; } } } } ll ans=0; for(i=0;i<=num;i++) ans=(ans+f[m][i][1])%10007; cout<<ans<<endl; }
没有人不辛苦,只有人不喊疼