分析:与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 ;
}

考研路茫茫--单词情结 - HDU 2243(AC自动机+矩阵乘法)的更多相关文章

  1. 考研路茫茫――单词情结 HDU - 2243(ac自动机 + 矩阵快速幂)

    考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  2. 考研路茫茫——单词情结 HDU - 2243 AC自动机 && 矩阵快速幂

    背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...

  3. POJ - 2778 ~ HDU - 2243 AC自动机+矩阵快速幂

    这两题属于AC自动机的第二种套路通过矩阵快速幂求方案数. 题意:给m个病毒字符串,问长度为n的DNA片段有多少种没有包含病毒串的. 根据AC自动机的tire图,我们可以获得一个可达矩阵. 关于这题的t ...

  4. hdu 2243 考研路茫茫——单词情结(AC自动+矩阵)

    考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  5. HDU 2243 考研路茫茫——单词情结(AC自动机+矩阵)

    考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. HDU 2243 考研路茫茫——单词情结

    考研路茫茫——单词情结 Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID ...

  7. hdu_2243_考研路茫茫——单词情结(AC自动机+矩阵)

    题目链接:hdu_2243_考研路茫茫——单词情结 题意: 让你求包含这些模式串并且长度不小于L的单词种类 题解: 这题是poj2788的升级版,没做过的强烈建议先做那题. 我们用poj2778的方法 ...

  8. hdu2243 考研路茫茫——单词情结【AC自动机】【矩阵快速幂】

    考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  9. HDU2243 考研路茫茫——单词情结 ——AC自动机、矩阵优化

    题目链接:https://vjudge.net/problem/HDU-2243 考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others)    Memor ...

随机推荐

  1. 转载[POJ题型分类]

    北大ACM题分类 主流算法: 1.搜索 //回溯 2.DP(动态规划) 3.贪心 4.图论 //Dijkstra.最小生成树.网络流 5.数论 //解模线性方程 6.计算几何 //凸壳.同等安置矩形的 ...

  2. Android手机修改Hosts的方法

    Android手机是和Google帐号紧密联系的,由于中国的操蛋情况,很多时候Google帐号无法登录,导致Android市场无法使用. 在电脑上我们通过修改Hosts方法可以解决Google帐号的登 ...

  3. 获取C++类成员变量的地址偏移

    今天有在校学生问怎么获取类中的成员变量的地址偏移量,这个应该是很多初学C++的人很好奇的问题.以前我在学校的时候,也有过这种需求.忘了当时是要写什么“奇怪的程序”了,反正需要获取一个类的成员变量的地址 ...

  4. 【vc】6_菜 单

    1.菜单命令响应函数: 提示:MFC都是采用大写字母来标识资源ID号的:为了区分资源类型,一般遵循这样一个原则:在“ID”字符串后加上一个标识资源类型的字母.例:菜单资源(Menu):ID_Mxxx: ...

  5. 五分钟看懂js关键字this

    this是js里面很常用的关键字,而灵活的js也赋予了这个关键字无穷的生命力,相信你也有被它糊弄的时候,我总结了一个6字原则,大部分场合都能清醒分辨this到底指向who,跟大家分享一下,欢迎指正. ...

  6. PHP下编码转换函数mb_convert_encoding与iconv的使用说明

    mb_convert_encoding这个函数是用来转换编码的. 不过英文一般不会存在编码问题,只有中文数据才会有这个问题.比如你用Zend Studio或Editplus写程序时,用的是gbk编码, ...

  7. Swiper的简单实用方法

    最近项目中有用到一个非常强大的组件idangerous.swiper.js的组件,这个组件能够实现幻灯片的播放效果,而且有各种3D效果,大家可以去试一下,效果很不错的说! 这是这个项目的api文档:h ...

  8. Android扫描二维码 实现 登录网页

    工程代码:ScanQRcode.zip ------------------------------------------------------------------ 1. 扫描二维码登录的实现 ...

  9. HTML部分标签的含义(3)

    1,<a>标签,链接到另一个页面 语法:<a href="目标网址" title=“鼠标滑过显示的文本”>链接显示的文本</a> title属性 ...

  10. linker command failed with exit code 1

    这种问题,通常出现在添加第三方库文件或者多人开发时. 这种问题一般是找不到文件而导致的链接错误. 我们可以从如下几个方面着手排查. 1.以如下错误为例,如果是多人开发,你同步完成后发现出现如下的错误. ...