分析:与poj的2778差不多的,求出来所有的情况然后减去不包含的就行了,这次使用了一下kuangbin的那种自动机写法,确实还不错,因为尤是在建立矩阵的时候更加方便。

 
代码如下:
===============================================================================================================================
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<iostream>
using namespace std; const int MAXN = ;
const int MAXM = ;
const int mod = ; struct Matrix
{///定义矩阵
int size;
unsigned long long edge[MAXN][MAXN]; Matrix(int Len)
{
size = Len;
memset(edge, false, sizeof(edge));
}
Matrix operator *(const Matrix &Map) const
{
Matrix ans(size); for(int i=; i<size; i++)
for(int j=; j<size; j++)
for(int k=; k<size; k++)
{
ans.edge[i][j] += edge[i][k] * Map.edge[k][j];
} return ans;
}
}; struct Ac_Trie
{
int next[MAXN][MAXM];
int fail[MAXN], End[MAXN];
int Len, root; Ac_Trie()
{
memset(next, -, sizeof(next));
memset(End, false, sizeof(End));
Len = , root = ;
} void Insert(char s[])
{
int p = root; for(int i=; s[i]; i++)
{
int k = s[i] - 'a'; if(next[p][k] == -)
next[p][k] = Len++;
p = next[p][k];
} End[p] = true;
} void GetFail()
{
queue<int> Q;
int p = root; fail[p] = root; for(int i=; i<MAXM; i++)
{
if(next[p][i] == -)
next[p][i] = root;
else
{
fail[next[p][i]] = root;
Q.push(next[p][i]);
}
} while(Q.size())
{
p = Q.front();
Q.pop(); for(int i=; i<MAXM; i++)
{
if(next[p][i] == -)
next[p][i] = next[fail[p]][i];
else
{
fail[next[p][i]] = next[fail[p]][i];
Q.push(next[p][i]);
}
} End[p] |= End[fail[p]];
}
} Matrix GetMatrix()
{
Matrix ans(Len+); for(int i=; i<Len; i++)
for(int k=; k<MAXM; k++)
{
if(End[next[i][k]] == false)
ans.edge[i][next[i][k]] += ;
} for(int i=; i<=Len; i++)
ans.edge[i][Len] = ; return ans;
}
}; Matrix QuickPow(long long K, Matrix Map)
{
Matrix ans(Map.size); for(int i=; i<ans.size; i++)
ans.edge[i][i] = ; while(K)
{
if(K & )
ans = ans * Map;
Map = Map * Map; K /= ;
} return ans;
} int main()
{
long long N, L; while(scanf("%lld%lld", &N, &L) != EOF)
{
char s[MAXN];
Ac_Trie a; while(N--)
{
scanf("%s", s);
a.Insert(s);
} a.GetFail();
Matrix ans = a.GetMatrix(); unsigned long long sum1=, sum=; ans = QuickPow(L, ans); for(int i=; i<ans.size; i++)
sum1 += ans.edge[][i]; ans.size = ;
ans.edge[][] = ;
ans.edge[][] = ;
ans.edge[][] = ans.edge[][] = ; ans = QuickPow(L, ans); sum = ans.edge[][] + ans.edge[][]; cout << sum - sum1 <<endl;
} return ;
}

最新文章

  1. sys.dm_tran_locks,
  2. Android里的多线程知识点
  3. QTP之delphi试用感想一(自动化测试)
  4. weapon制作武器
  5. global中拦截404错误的实现方法
  6. Atitit..文件上传组件选择and最佳实践的总结(2)----HTTP
  7. D - 小Y上学记——要迟到了!
  8. flash 右键菜单隐藏与修改
  9. ActiveMQ持久化消息的三种方式
  10. python实例编写(1)--浏览器操作,元素操作
  11. Java8之Optional类
  12. wpf binging(三) 绑定方法的返回值
  13. 联想项目结束了,聊聊华为SAP HANA项目八卦
  14. 转载:必须收藏!50个最流行的免费Kubernetes工具集
  15. js通用绑定事件函数
  16. P1330 封锁阳光大学
  17. js判断字符串是否json格式
  18. 超分辨率论文CVPR-Kai Zhang
  19. 深入理解JAVA集合系列四:ArrayList源码解读
  20. Rolling in the Deep (Learning)

热门文章

  1. Android学习笔记(广播机制)
  2. 解读oracle执行计划-待续
  3. 关键字throw(something)限制
  4. 命令模式(Command)
  5. OC文件操作(2)
  6. java获取数据库数据表的元数据
  7. centos6.2下搭建Web服务器
  8. 初涉JavaScript模式 (1) : 简介
  9. sphinx (coreseek)——3、区段查询 与 增量索引实例
  10. h.264语法结构分析