[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

 

posted @ 2020-08-02 11:48  朝暮不思  阅读(133)  评论(0编辑  收藏  举报