1. 程式人生 > 實用技巧 >[JSOI2007]文字生成器 (AC自動機)

[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; }
View Code