记录编号 182203 评测结果 AAAAAAAAAA
题目名称 [SPOJ 1676]文本生成器 最终得分 100
用户昵称 Gravatarmikumikumi 是否通过 通过
代码语言 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;
}