和前几天做的AC自动机类似。

  思路简单但是代码200余行。。

  假设solve_sub(i)表示长度为i的不含危险单词的总数。

  最终答案为用总数(26^1+26^2+...+26^n)减去(solve_sub(1)+solve_sub(2)+...+solve_sub(n))。前者构造f[i]=f[i-1]*26+26然后矩阵快速幂即可(当然也可以分治的方法)。后者即构造出dp矩阵p,然后计算(p^1+p^2+...+p^n),对其分治即可。

  代码如下:

 #include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
#include <iostream>
using namespace std;
const int MAX_Tot = + ;
const int mod = ;
typedef unsigned long long ull; int m,n; struct matrix
{
ull e[MAX_Tot][MAX_Tot];
int n,m;
matrix() {}
matrix(int _n,int _m): n(_n),m(_m) {memset(e,,sizeof(e));}
matrix operator * (const matrix &temp)const
{
matrix ret = matrix(n,temp.m);
for(int i=;i<=ret.n;i++)
{
for(int j=;j<=ret.m;j++)
{
for(int k=;k<=m;k++)
{
ret.e[i][j] += e[i][k]*temp.e[k][j];
}
}
}
return ret;
}
matrix operator + (const matrix &temp)const
{
matrix ret = matrix(n,m);
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
ret.e[i][j] += e[i][j]+temp.e[i][j];
}
}
return ret;
}
void getE()
{
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
e[i][j] = i==j?:;
}
}
}
}; matrix qpow(matrix temp,int x)
{
int sz = temp.n;
matrix base = matrix(sz,sz);
base.getE();
while(x)
{
if(x & ) base = base * temp;
x >>= ;
temp = temp * temp;
}
return base;
} matrix solve(matrix a, int k)
{
if(k == ) return a;
int n = a.n;
matrix temp = matrix(n,n);
temp.getE();
if(k & )
{
matrix ex = qpow(a,k);
k--;
temp = temp + qpow(a,k/);
return temp * solve(a,k/) + ex;
}
else
{
temp = temp + qpow(a,k/);
return temp * solve(a,k/);
}
} struct Aho
{
struct state
{
int nxt[];
int fail,cnt;
}stateTable[MAX_Tot]; int size; queue<int> que; void init()
{
while(que.size()) que.pop();
for(int i=;i<MAX_Tot;i++)
{
memset(stateTable[i].nxt,,sizeof(stateTable[i].nxt));
stateTable[i].fail = stateTable[i].cnt = ;
}
size = ;
} void insert(char *s)
{
int n = strlen(s);
int now = ;
for(int i=;i<n;i++)
{
char c = s[i];
if(!stateTable[now].nxt[c-'a'])
stateTable[now].nxt[c-'a'] = size++;
now = stateTable[now].nxt[c-'a'];
}
stateTable[now].cnt = ;
} void build()
{
stateTable[].fail = -;
que.push(); while(que.size())
{
int u = que.front();que.pop();
for(int i=;i<;i++)
{
if(stateTable[u].nxt[i])
{
if(u == ) stateTable[stateTable[u].nxt[i]].fail = ;
else
{
int v = stateTable[u].fail;
while(v != -)
{
if(stateTable[v].nxt[i])
{
stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];
// 在匹配fail指针的时候顺便更新cnt
if(stateTable[stateTable[stateTable[u].nxt[i]].fail].cnt == )
stateTable[stateTable[u].nxt[i]].cnt = ;
break;
}
v = stateTable[v].fail;
}
if(v == -) stateTable[stateTable[u].nxt[i]].fail = ;
}
que.push(stateTable[u].nxt[i]);
}
/*****建立自动机nxt指针*****/
else
{
if(u == ) stateTable[u].nxt[i] = ;
else
{
int p = stateTable[u].fail;
while(p != - && stateTable[p].nxt[i] == ) p = stateTable[p].fail;
if(p == -) stateTable[u].nxt[i] = ;
else stateTable[u].nxt[i] = stateTable[p].nxt[i];
}
}
/*****建立自动机nxt指针*****/
}
}
} matrix build_matrix()
{
matrix ans = matrix(size,size);
for(int i=;i<size;i++)
{
for(int j=;j<;j++)
{
if(!stateTable[i].cnt && !stateTable[stateTable[i].nxt[j]].cnt)
ans.e[i+][stateTable[i].nxt[j]+]++;
}
}
return ans;
}
}aho; void print(matrix p)
{
int n = p.n;
int m = p.m;
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
printf("%d ",p.e[i][j]);
}
puts("");
}
} int main()
{
while(scanf("%d%d",&m,&n) == )
{
aho.init();
char s[];
for(int i=;i<=m;i++)
{
scanf("%s",s);
aho.insert(s);
}
aho.build();
matrix p = aho.build_matrix();
p = solve(p,n);
ull temp = ;
for(int i=;i<=aho.size;i++) temp += p.e[][i];
matrix t = matrix(,);
t.e[][] = ;
matrix A = matrix(,);
A.e[][] = A.e[][] = ; A.e[][] = ;
t = t * qpow(A,n);
ull ans = t.e[][] - temp;
printf("%llu\n",ans);
}
return ;
}

  最后觉得,,我之前矩阵模板里的print()真好用啊233= =。

最新文章

  1. 对 Linux 新手非常有用的 20 个命令
  2. dede模板完全控制攻略
  3. cf602A Two Bases
  4. hdu4336压缩率大方的状态DP
  5. regular expression tutorial
  6. VR全景智慧城市——宣传再华丽,不如用户亲身参与
  7. 【集合框架】JDK1.8源码分析之HashMap(一) 转载
  8. python之路--反射
  9. LOJ #6053. 简单的函数
  10. jquery源码中noConflict(防止$和jQuery的命名冲突)的实现原理
  11. Sql Server 增加字段、修改字段、修改类型、修改默认值
  12. Mysql 中如何创建数据库和数据表
  13. 三种简洁的经典高效的DIV+CSS制作的Tab导航简析
  14. 【BZOJ】【2127】happiness
  15. 《Python自动化测试修炼宝典》线上课程已经成功入驻网易云课堂......
  16. 如何将svg图标快速转换成字体图标?
  17. 分页技巧__在项目中使用QueryHelper辅助对象实现分页效果
  18. ant+jmeter+jenkins+git持续集成以及邮件报告展示
  19. 利用canvas制作图片(可缩放和平移)+相框+文字
  20. HDU 4305 Lightning Matrix Tree定理

热门文章

  1. 再谈 pm2
  2. Citrix ADC 12.1 / NetScaler 12
  3. 【多进程】php实现 master-worker 守护多进程模式
  4. json其实就是一种数据格式
  5. MHA-结合MySQL半同步复制高可用集群(Centos7)
  6. smart_ptr之shared_ptr
  7. 服务器CPU架构演变过程
  8. DoD与TCP/IP
  9. Canal的简单使用(监控数据库数据的变化)
  10. 用js刷剑指offer(顺时针打印数组)