SPOJ 1676 GEN - Text Generatord

来源:互联网 发布:出入无时 莫知其乡 编辑:程序博客网 时间:2024/06/17 02:42

一眼题。。。。。

论文里讲了一大堆其实就是ac自动机上乱搞嘛。

然后就是论如何把一道水题出成神题,技巧就是……卡常数。。。。。。。

首先会发现某些情况下trie树的很多节点都到不了(比如说根节点的A子节点是叶子,于是所有串只要到A全都cut了)

所以存在大量的无用状态,全部剪掉就能过了。

话说现在才发现原来ac自动机的fail指针和kmp的fail一样可以通过一个循环遍历所有的(既是前缀又是后缀的逗比)

#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;typedef long long ll;const int N=60+5;const int p=(1e4)+7;int m;struct matrix{ll a[N][N];matrix(){memset(a,0,sizeof(a));}void clear(){memset(a,0,sizeof(a));}void print(){for(int i=0;i<=m;i++){for(int j=0;j<=m;j++)printf("%d ",a[i][j]);putchar('\n');}}matrix operator * (const matrix &b)const{static matrix ans;ans.clear();for(int i=0;i<=m;i++)for(int j=0;j<=m;j++)for(int k=0;k<=m;k++)ans.a[i][j]+=a[i][k]*b.a[k][j];for(int i=0;i<=m;i++)for(int j=0;j<=m;j++)ans.a[i][j]%=p;return ans;}matrix operator ^ (int k)const{static matrix ans,b;ans.clear();memcpy(b.a,a,sizeof(a));for(int i=0;i<=m;i++)ans.a[i][i]=1;for(;k;k>>=1,b=b*b)if(k&1)ans=ans*b;return ans;}};ll g[N][N];struct Node{int fail,ch[26],val;void clear(){fail=val=0;memset(ch,0,sizeof(ch));}}tr[N];void ins(char *s){int u;for(u=0;*s;s++){int c=(*s)-'A';if(!tr[u].ch[c]){tr[u].ch[c]=++m;tr[m].clear();}u=tr[u].ch[c];}tr[u].val++;}void bfs(){queue<int>q;q.push(0);while(!q.empty()){int u=q.front();q.pop();for(int i=0;i<26;i++)if(tr[u].ch[i]){int v=tr[u].ch[i];if(u)tr[v].fail=tr[tr[u].fail].ch[i];q.push(v);}else tr[u].ch[i]=tr[tr[u].fail].ch[i];}}int idx[N];void bfs2(){queue<int>q;q.push(0);int sz=0;memset(idx,0,sizeof(idx));while(!q.empty()){int u=q.front();q.pop();for(int i=0;i<26;i++){int v=tr[u].ch[i];bool flag=true;for(int p=v;p;p=tr[p].fail)if(tr[p].val){flag=false;break;}if(!flag)continue;if(v&&!idx[v]){idx[v]=++sz;q.push(v);}g[idx[u]][idx[v]]++;}}m=sz;}int qmul(int a,int b){int ans=1;for(;b;b>>=1,a=a*a%p)if(b&1)ans=ans*a%p;return ans;}char s[15];int main(){//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);int n,l;while(~scanf("%d%d",&n,&l)){ m=0;tr[0].clear(); while(n--){ scanf("%s",s); ins(s); } memset(g,0,sizeof(g)); bfs(); bfs2(); static matrix A; memcpy(A.a,g,sizeof(g)); A=A^l; int ans=0; for(int i=0;i<=m;i++) ans=(ans+A.a[0][i])%p; ans=((qmul(26,l)-ans)%p+p)%p; printf("%d\n",ans);}return 0;}


0 0
原创粉丝点击