记录编号 |
182203 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[SPOJ 1676]文本生成器 |
最终得分 |
100 |
用户昵称 |
mikumikumi |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.126 s |
提交时间 |
2015-08-27 14:18:40 |
内存使用 |
0.34 MiB |
显示代码纯文本
- #include<iostream>
- #include<cstdio>
- #include<cmath>
- #include<algorithm>
- #include<cstring>
- #include<vector>
- #include<queue>
- #include<iomanip>
- using namespace std;
- int N,L;
- string str[20];
- int match[12]={0};//单词可以匹配的最大长度
- int s[12][8]={0};//单词i前j被匹配时的状态编号,s[0][0]代表空串,编号为1
- pair<int,int> stat[96];
- int mod=10007;
- int S;//总状态数
- class miku
- {
- public:
- int s[62][62];
- int m,n;//列和行
- miku()
- {
- m=n=0;
- memset(s,0,sizeof(s));
- }
- void print()
- {
- cout<<m<<" "<<n<<endl;
- for(int i=1;i<=n;i++)
- {
- for(int j=1;j<=m;j++)
- cout<<s[i][j]<<" ";
- cout<<endl;
- }
- }
- void make(int sn)
- {
- n=m=sn;
- for(int i=1;i<=n;i++)
- s[i][i]=1;
- }
- }G,D;
- miku operator * (miku a,miku b)
- {
- miku c;
- c.n=a.n;c.m=b.m;
- for(int i=1;i<=c.n;i++)
- for(int j=1;j<=c.m;j++)
- for(int k=1;k<=a.m;k++)
- {
- c.s[i][j]+=a.s[i][k]*b.s[k][j];
- c.s[i][j]%=mod;
- }
- return c;
- }
- inline miku quickpow(miku a,int b)
- {
- miku c;
- c.make(a.n);
- //c.print();
- while(b)
- {
- if(b&1) c=c*a;
- a=a*a;b>>=1;
- }
- return c;
- }
- int qmi(int y)
- {
- int re=1;
- int x=26;
- while(y>0)
- {
- if(y&1) re*=x;
- y>>=1;x*=x;re%=mod;x%=mod;
- }
- return re;
- }
- int find(string tem,int k)
- {
- int start=tem.size()-k;
- int i,j;
- for(i=1;i<=N;i++)
- {
- if(str[i].size()<k) continue;
- for(j=0;j<k;j++) if(str[i][j]!=tem[start+j]) goto NEXT;
- if(j==str[i].size()||j-1>match[i]) return -1;
- return i;
- NEXT:;
- }
- return 0;
- }
- int mamatch(string tem)
- {
- pair<int,int> ans;
- ans=make_pair(0,0);
- int j;
- for(int k=tem.size();k>=1;k--)
- {
- j=find(tem,k);
- if(j==-1) return 0;
- if(j)
- {
- ans=make_pair(j,k-1);
- break;
- }
- }
- return s[ans.first][ans.second];
- }
- void update()
- {
- int tot=1;//当前状态的编号
- s[0][0]=tot;stat[tot]=make_pair(0,-1);match[0]=-1;
- string tem;
- for(int i=1;i<=N;i++)
- {
- tem="\0";
- match[i]=str[i].size()-2;
- for(int j=0;j<str[i].size();j++)
- {
- tem+=str[i][j];
- //cout<<tem<<endl;
- int t;
- for(int k=1;k<=N;k++)
- {
- for(t=0;t<str[k].size();t++)
- {
- if(str[k][str[k].size()-1-t]!=tem[tem.size()-1-t]) break;
- }
- if(t==str[k].size())//完全匹配
- {
- match[i]=j-1;
- goto NEXT;
- //cout<<tem<<
- }
- }
- s[i][j]=++tot;
- stat[tot]=make_pair(i,j);
- //cout<<stat[tot].first<<" "<<stat[tot].second<<" "<<tot<<endl;
- }
- NEXT:;
- }
- S=tot;
- G.n=1;G.m=S;
- //cout<<S<<endl;
- for(int i=1;i<=S;i++) G.s[1][i]=1;
- D.m=D.n=S;
- for(int i=1;i<=S;i++)
- {
- tem="\0";
- for(int j=0;j<=stat[i].second;j++) tem+=str[stat[i].first][j];
- for(int j=0;j<26;j++)
- {
- int k=mamatch(tem+char(j+'A'));
- if(k) D.s[k][i]++;
- //cout<<k<<endl;
- }
- //cout<<tem<<endl;
- }
- }
- void work()
- {
- str[0]="\0";
- update();
- int ans=qmi(L);
- G=G*quickpow(D,L);
- ans-=G.s[1][1];
- ans=(ans+mod)%mod;
- printf("%d",ans);
- }
- int main()
- {
- freopen("textgen.in","r",stdin);
- freopen("textgen.out","w",stdout);
- scanf("%d%d",&N,&L);
- for(int i=1;i<=N;i++)
- cin>>str[i];
- work();
- return 0;
- }