hdu2243
一天,Lele在某本单词书上看到了一个根据词根来背单词的方法。比如"ab",放在单词前一般表示"相反,变坏,离去"等。
于是Lele想,如果背了N个词根,那这些词根到底会不会在单词里出现呢。更确切的描述是:长度不超过L,只由小写字母组成的,至少包含一个词根的单词,一共可能有多少个呢?这里就不考虑单词是否有实际意义。
比如一共有2个词根 aa 和 ab ,则可能存在104个长度不超过3的单词,分别为
(2个) aa,ab,
(26个)aaa,aab,aac...aaz,
(26个)aba,abb,abc...abz,
(25个)baa,caa,daa...zaa,
(25个)bab,cab,dab...zab。
这个只是很小的情况。而对于其他复杂点的情况,Lele实在是数不出来了,现在就请你帮帮他。
aa ab
1 2
a
52
#include<cstring>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
typedef unsigned long long LL;
struct Mat
{
LL mat[36][36];
int n;
Mat(int _n)
{
n=_n;
memset(mat,0,sizeof(mat));
}
Mat operator *(const Mat &B)const
{
Mat C(n);
for(int k=0; k<n; ++k)
for(int i=0; i<n; ++i)
{
if(mat[i][k]==0) continue;
for(int j=0; j<n; ++j)
{
if(B.mat[k][j]==0) continue;
C.mat[i][j]=C.mat[i][j]+mat[i][k]*B.mat[k][j];
}
}
return C;
}
Mat operator ^(int k)
{
Mat C(n);
for(int i=0; i<n; ++i) C.mat[i][i]=1;
while(k)
{
if(k&1) C=C*(*this),--k;
k>>=1;
*this=(*this)*(*this);
}
return C;
}
};
struct AC
{
int ch[38][26],fail[38],val[38],sz,rt;
void init()
{
sz=rt=0;
memset(ch[rt],-1,sizeof(ch[rt]));
}
void insert(char *str)
{
int len=strlen(str),u=rt;
for(int i=0; i<len; ++i)
{
if(ch[u][str[i]-'a']==-1)
{
++sz;
memset(ch[sz],-1,sizeof(ch[sz]));
val[sz]=0;
ch[u][str[i]-'a']=sz;
}
u=ch[u][str[i]-'a'];
}
val[u]=1;
}
void build()
{
queue<int>Q;
int u=rt;
for(int i=0; i<26; ++i)
{
if(ch[u][i]==-1) ch[u][i]=rt;
else
{
fail[ch[u][i]]=rt;
Q.push(ch[u][i]);
}
}
while(!Q.empty())
{
u=Q.front();
Q.pop();
val[u]|=val[fail[u]];
for(int i=0; i<26; ++i)
{
if(ch[u][i]==-1) ch[u][i]=ch[fail[u]][i];
else
{
fail[ch[u][i]]=ch[fail[u]][i];
Q.push(ch[u][i]);
}
}
}
}
Mat get()
{
Mat ret(sz+2);
for(int i=0; i<=sz; ++i)
for(int j=0; j<26; ++j)
if(!val[ch[i][j]]) ++ret.mat[i][ch[i][j]];
for(int i=0; i<=sz+1; ++i)
ret.mat[i][sz+1]=1;
return ret;
}
} ac;
char s[55];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
ac.init();
for(int i=0; i<n; ++i)
{
scanf("%s",s);
ac.insert(s);
}
ac.build();
Mat A=ac.get();
A=A^m;
LL res=0;
for(int i=0; i<A.n; ++i)
res+=A.mat[0][i];
--res;
A=Mat(2);
A.mat[0][0]=26;
A.mat[1][1]=A.mat[0][1]=1;
A=A^m;
Mat B(2);
B.mat[0][0]=B.mat[1][0]=1;
A=A*B;
LL ans=A.mat[0][0];
ans-=res+1;
cout<<ans<<endl;
}
}
hdu2243的更多相关文章
- 【AC自动机】【矩阵乘法】【等比数列】hdu2243 考研路茫茫——单词情结
题解:http://blog.csdn.net/xingyeyongheng/article/details/10005923 这里采用了二分法求等比数列前n项和. 等比数列前n项和也可以用矩乘快速幂 ...
- HDU2243 考研路茫茫——单词情结 ——AC自动机、矩阵优化
题目链接:https://vjudge.net/problem/HDU-2243 考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memor ...
- HDU-2243 考研路茫茫——单词情结(AC自动机)
题目大意:给n个单词,长度不超过L的单词有多少个包含n个单词中的至少一个单词. 题目分析:用长度不超过L的单词书目减去长度在L之内所有不包含任何一个单词的书目. 代码如下: # include< ...
- hdu2243考研路茫茫——单词情结(ac+二分矩阵)
链接 跟2778差不多,解决了那道题这道也不成问题如果做过基本的矩阵问题. 数比较大,需要用unsigned longlong 就不需要mod了 溢出就相当于取余 #include <iostr ...
- HDU2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
与POJ2778一样.这题是求长度不超过n且包含至少一个词根的单词总数. 长度不超过n的单词总数记为Sn,长度不超过n不包含词根的单词总数记为Tn. 答案就是,Sn-Tn. Sn=26+262+263 ...
- POJ2778&HDU2243&POJ1625(AC自动机+矩阵/DP)
POJ2778 题意:只有四种字符的字符串(A, C, T and G),有M中字符串不能出现,为长度为n的字符串可以有多少种. 题解:在字符串上有L中状态,所以就有L*A(字符个数)中状态转移.这里 ...
- hdu2243考研路茫茫——单词情结
Problem Description 背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如&q ...
- hdu2243之AC自动机+矩阵乘法
考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- HDU2243 考研路茫茫――单词情结
Description 背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab&q ...
- hdu2243 考研路茫茫——单词情结【AC自动机】【矩阵快速幂】
考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
随机推荐
- jdbc批量插入数据
//插入很多书(批量插入用法) public void insertBooks(List<Book> book) { final List<Book> tempBook=b ...
- 自建Git服务器 - 创建属于你自己的代码仓库
最近有线上朋友私信问我怎么搭建个人博客,也有咨询我个人项目的代码是如何保管的,还有一个朋友问我买了服务器玩了一段时间,等新鲜感过了就不知道做什么了. 关于这些问题并没有一个标准答案,每个人都有自己的使 ...
- mac OS git关联github
正在更新 mac OS 默认安装了git git -v 查看版本 mac OS 默认安装了ssh ssh -v 查看版本 1.设置username和email(github每次commit都会记录 ...
- Linux / mac OS Shell常用命令
一.文件.目录操作命令 1.ls命令 功能:显示文件和目录的信息 ls 以默认方式显示当前目录文件列表 ls -a 显示所有文件包括隐藏文件 ls -l 显示文件属性,包括大小,日期,符号连接,是否可 ...
- VS Code 全部快捷键一览表(巨TM全)
常用 General 按 Press 功能 Function Ctrl + Shift + P,F1 显示命令面板 Show Command Palette Ctrl + P 快速打开 Quick O ...
- P3842 [TJOI2007]线段
最近多刷些dp,觉得这个算不上蓝题 在一个\(n\times n\)的平面上,在每一行中有一条线段,第\(i\)行的线段的左端点是\((i, L_i)\),右端点是\((i, R_i)\),其中\ ...
- MySQL必知必会1-20章读书笔记
MySQL备忘 目录 目录 使用MySQL 检索数据 排序检索数据 过滤数据 数据过滤 用通配符进行过滤 用正则表达式进行搜索 创建计算字段 使用数据处理函数 数值处理函数 汇总数据 分组数据 使用子 ...
- IOS抓取与反抓取
目录 IOS抓取基础知识 IOS抓取方式 iOS破解 模拟器 黑雷苹果模拟器 介绍 局限 改机软件 常用改机软件 检测 可更改属性 注入与Hook(越狱下实现作弊) 注入方式 Hook方式 重打包(非 ...
- Jmeter的简单使用
前言 对于jmeter的使用有很多内容,本章节只是简单介绍jmeter的两个方面的内容:一个是使用jmeter模拟postman发送http请求,一个是使用jmete进行压力测试. 更多的内容请参考官 ...
- C. Game with Chips(陷阱暴力题)
\(为什么说这是个陷阱呢??\) \(因为不管你脑洞多大,数学多好,都发现会束手无策\) \(每移动一次不知道往哪个方向,不知道先访问哪个点,同时要记录所有点的坐标,记录每个点是否访问过目标点.... ...