Description

背单词,始终是复习英语的重要环节。在荒废了3年大学生涯后,Lele也终于要开始背单词了。 
一天,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实在是数不出来了,现在就请你帮帮他。

 

Input

本题目包含多组数据,请处理到文件结束。 
每组数据占两行。 
第一行有两个正整数N和L。(0<N<6,0<L<2^31) 
第二行有N个词根,每个词根仅由小写字母组成,长度不超过5。两个词根中间用一个空格分隔开。 
 

Output

对于每组数据,请在一行里输出一共可能的单词数目。 
由于结果可能非常巨大,你只需要输出单词总数模2^64的值。 
 

Sample Input

2 3
aa ab
1 2
a
 

Sample Output

104
52
 
容斥
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; inline int f(char u){
return u-'a';
}
struct tree{
int f;
bool w;
int t[];
}t[];
int n,m,num=;
struct MX{
unsigned long long c[][];
};
char s[];
bool ma[],us[];
queue <int> q;
MX a,o;
inline bool dfs(int x){
if (x==) return ;
if (t[x].w) return ;
if (us[x]) return ma[x];
us[x]=;
return ma[x]=dfs(t[x].f);
}
inline void in(){
int p=,l,m=strlen(s);
for (register int i=;i<m;i++){
l=f(s[i]);
if (!t[p].t[l]) t[p].t[l]=++num;
p=t[p].t[l];
}
t[p].w=;
}
inline void mafa(){
register int i;int k,p;
q.push();t[].f=;
while(!q.empty()){
k=q.front();q.pop();
for (i=;i<;i++)
if (t[k].t[i]){
p=t[k].f;
while((!t[p].t[i])&&p) p=t[p].f;
t[t[k].t[i]].f=(k==p)?:t[p].t[i];
q.push(t[k].t[i]);
}
}
}
inline MX cheng(MX x,MX y){
register int i,j,k;
MX z;
for (i=;i<=num;i++)
if (ma[i])
for (j=;j<=num;j++)
if (ma[j]){
z.c[i][j]=;
for (k=;k<=num;k++)
if (ma[k])
z.c[i][j]+=x.c[i][k]*y.c[k][j];
}
return z;
}
inline MX mi(MX x,int b){
register int i,j;
MX z=x;b--;
while(b){
if (b&) z=cheng(z,x);
b>>=;
x=cheng(x,x);
}
return z;
}
int main(){
register int i,j;int u;
unsigned long long ans;
while(~scanf("%d%d",&n,&m)){
u=ans=;
for (i=;i<=num;i++)
for (j=;j<;j++) t[i].t[j]=;
for (i=;i<=num;i++) ma[i]=us[i]=t[i].w=t[i].f=;
num=;
a.c[][]=;
a.c[][]=a.c[][]=;
ma[]=ma[]=;
o=mi(a,m);
ma[]=ma[]=;
ans=o.c[][]+o.c[][];
for (i=;i<=num;i++)
for (j=;j<=num;j++)
a.c[i][j]=;
num=;
for (i=;i<=n;i++){
scanf("%s",s);
in();
}
mafa();
for (i=;i<=num;i++)
ma[i]=dfs(i);
for (i=;i<=num;i++)
if (ma[i])
for (j=;j<;j++){
if (!t[i].t[j]){
u=t[i].f;
while(!t[u].t[j]&&u)u=t[u].f;
u=t[u].t[j];
}else u=t[i].t[j];
a.c[i][u]++;
}
num++;
ma[num]=;
for (i=;i<=num;i++) a.c[i][num]=;
o=mi(a,m);
for (i=;i<=num;i++)
if (ma[i])
ans-=o.c[][i];
for (i=;i<=num;i++)
for (j=;j<=num;j++)
a.c[i][j]=;
printf("%llu\n",ans);
}
}

HDU2243 考研路茫茫――单词情结的更多相关文章

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

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

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

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

  3. HDU-2243 考研路茫茫——单词情结(AC自动机)

    题目大意:给n个单词,长度不超过L的单词有多少个包含n个单词中的至少一个单词. 题目分析:用长度不超过L的单词书目减去长度在L之内所有不包含任何一个单词的书目. 代码如下: # include< ...

  4. HDU2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)

    与POJ2778一样.这题是求长度不超过n且包含至少一个词根的单词总数. 长度不超过n的单词总数记为Sn,长度不超过n不包含词根的单词总数记为Tn. 答案就是,Sn-Tn. Sn=26+262+263 ...

  5. hdu2243考研路茫茫——单词情结

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

  6. 【AC自动机】【矩阵乘法】【等比数列】hdu2243 考研路茫茫——单词情结

    题解:http://blog.csdn.net/xingyeyongheng/article/details/10005923 这里采用了二分法求等比数列前n项和. 等比数列前n项和也可以用矩乘快速幂 ...

  7. [hdu2243]考研路茫茫——单词情结(AC自动机+矩阵快速幂)

    题意:长度不超过L,只由小写字母组成的,至少包含一个词根的单词,一共可能有多少个. 解题关键:利用补集转化的思想,先求一个词根也不包含的单词个数,然后用总的减去即可.长度不超过L需要用矩阵维数增加一倍 ...

  8. hdu2243考研路茫茫——单词情结(ac+二分矩阵)

    链接 跟2778差不多,解决了那道题这道也不成问题如果做过基本的矩阵问题. 数比较大,需要用unsigned longlong 就不需要mod了 溢出就相当于取余 #include <iostr ...

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

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

随机推荐

  1. 转:iOS开发之多种Cell高度自适应实现方案的UI流畅度分析

    本篇博客的主题是关于UI操作流畅度优化的一篇博客,我们以TableView中填充多个根据内容自适应高度的Cell来作为本篇博客的使用场景.当然Cell高度的自适应网上的解决方案是铺天盖地呢,今天我们的 ...

  2. JaveScript流程控制(JS知识点归纳四)

    01 流程控制 顺序结构: 程序的默认执行方式 条件判断语句:也称之为分支结构,选择结构:如果程序要执行的代码出现了多种情况需要使用 循环结构:当代码需要多次重复执行多次时,使用 02 条件判断语句 ...

  3. Sum of odd and even elements

    Given an integer N, you have to print the sum of odd numbers and even numbers form 1 to N Input:Firs ...

  4. HTML基本功之文档结构

    项目名 首页 命名为 index.html 样式文件夹 命名为 css  /*用来放样式文件*/ base.css  /*基本样式*/ index.css /*首页样式*/ global.css /* ...

  5. Python-String字符串的相关方法

  6. Linux发行版 CentOS6.5下删除分区操作

    本文地址http://comexchan.cnblogs.com/,作者Comex Chan,尊重知识产权,转载请注明出处,谢谢!   有时候,发现分区分错了.需要删除分区,只需按照分区的步骤逆向操作 ...

  7. python 中一些关键字的区别

    一.raw_input 和input input和raw_input都可以读取控制台的输入,但是input和raw_input在处理数字时是有区别的 1.当输入为纯数字时 input返回的是数值类型, ...

  8. Logback分别打印info日志和error日志

    <?xml version="1.0" encoding="utf-8" ?><configuration> <appender ...

  9. python科学计算_numpy_广播与下标

    多维数组下标 多维数组的下标是用元组来实现每一个维度的,如果元组的长度比维度大则会出错,如果小,则默认元组后面补 : 表示全部访问: 如果一个下标不是元组,则先转换为元组,在转换过程中,列表和数组的转 ...

  10. jQuery 实现无限任意添加下拉菜单

    新学jQuery还有很多没学,今天做了个下拉菜单,按照自己的思想结合学的基础效果实现一款可以任意添加层数的下拉菜单,如果有什么建议,欢迎指教啦啦啦 我喜欢备注细一些,这样给自己也是一种理解和方便回顾哈 ...