hdu 2433 考研路茫茫——单词情结 ac自动机+矩阵快速幂+dp

来源:互联网 发布:美女图片采集源码 编辑:程序博客网 时间:2024/05/22 15:26

题意:

和poj2778很像,这个是求包含病毒串的有多少个。那么我们求出不包含的在用总数相减就可以得到答案。

///对于2^64取mod 可以直接用unsigned long long

ACcode:

#include <bits/stdc++.h>#define maxn 160#define ll unsigned long longusing namespace std;int m;ll N;char str[33];struct Aho{    struct state{        int next[26];        int fail,cnt;    }s[maxn];    int size;    queue<int>q;    void init(){        size=1;        for(int i=0;i<maxn;++i){            memset(s[i].next,-1,sizeof(s[i].next));            s[i].fail=s[i].cnt=0;        }        while(q.size())q.pop();    }    void insert(char *str){        int n=strlen(str);        int now=0;        for(int i=0;i<n;++i){            int id=str[i]-'a';            if(s[now].next[id]==-1)                s[now].next[id]=size++;            now=s[now].next[id];        }        s[now].cnt=1;    }    struct Matrix{        ll mat[maxn][maxn];    };    Matrix mul(Matrix a,Matrix b){        Matrix ret;        memset(ret.mat,0,sizeof(ret.mat));        for(int i=0;i<size;++i)            for(int j=0;j<size;++j)                for(int k=0;k<size;++k)                    ret.mat[i][j]+=a.mat[i][k]*b.mat[k][j];        return ret;    }    Matrix pow(Matrix a,ll k){        Matrix ret;        memset(ret.mat,0,sizeof(ret.mat));        for(int i=0;i<size;++i)ret.mat[i][i]=1;        while(k){            if(k&1)ret=mul(ret,a);            a=mul(a,a);            k>>=1;        }        return ret;    }    void build(){        s[0].fail=0;        for(int i=0;i<26;++i)            if(s[0].next[i]==-1)                s[0].next[i]=0;            else {                s[s[0].next[i]].fail=0;                q.push(s[0].next[i]);            }        while(q.size()){            int u=q.front();q.pop();            if(s[s[u].fail].cnt)s[u].cnt=1;            for(int i=0;i<26;++i){                if(s[u].next[i]==-1)                    s[u].next[i]=s[s[u].fail].next[i];                else {                    s[s[u].next[i]].fail=s[s[u].fail].next[i];                    q.push(s[u].next[i]);                }            }        }        Matrix tmp;        memset(tmp.mat,0,sizeof(tmp.mat));        for(int i=0;i<size;++i){            if(s[i].cnt)continue;            for(int j=0;j<26;++j)                if(!s[s[i].next[j]].cnt)                tmp.mat[i][s[i].next[j]]++;        }        for(int i=0;i<=size;++i)            tmp.mat[i][size]=1;        size++;        tmp=pow(tmp,N);        ll ans=0;        for(int i=0;i<size;++i)            ans=(ans+tmp.mat[0][i]);        Matrix temp;        memset(temp.mat,0,sizeof(temp.mat));        temp.mat[0][0]=26;        temp.mat[1][0]=temp.mat[1][1]=1;        temp=pow(temp,N);        ll res=0;        for(int i=0;i<size;++i)res=(res+temp.mat[i][0]);        cout<<res-ans<<'\12';    }}aho;int main(){    while(cin>>m>>N){        aho.init();        for(int i=0;i<m;++i){            scanf("%s",str);            aho.insert(str);        }        aho.build();    }    return 0;}


0 0