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. Principle-初步认识(简介)

    Principle官网 探究了一下 . 呃--作出了下边这玩意 做的好的是这样的,瞬间把自己给菜了,给大家看看,设计需要UI功夫啊 把这个用上你的界面就搞基了,图形在水平.垂直上的动态效果(*.*) ...

  2. iOS开发--数据库管理CoreData的使用

    CoreData是iOS5后,苹果提供的原生的用于对象化管理数据并且持久化的框架.CoreData本质上是将底层数据库封装成对象进行管理.但数据库实际上只是CoreData的一个功能,并不是全部功能. ...

  3. 三菱Q系列PLC的io分配

    1.系统基本配置 2.存储卡配置 3.外部IO标号 4.主基板IO模块的IO号分配 5.扩展基板IO口标号 6.标准配置实例 7. 一.输入采样阶段 在输入采样阶段,可编程逻辑控制器以扫描方式依次地读 ...

  4. Java 伙伴系统(模拟)

    参考:https://labrick.cc/2015/10/12/buddy-system-algorithm/ 代码过烂 不宜参考. output: [operating.entity.Heap@4 ...

  5. 我是这样学习使用google学术的

    本科期间一直在cnki上面检索论文,随着科研能力的需要,部分论文在cnki的局限性就体现出来了,我就开始培养自己的文献检索能力.现在的各种开发工具,各种论文检索网站再加上文献检索的形式越来越复杂,我们 ...

  6. vue2 vue-rout

    vue 2.0的路由比起1.0简单了许多,分为以下几个步骤: 1.创建路由块和视图块: to里面是要切换的路径名称 <div id="app"> <div> ...

  7. 如何配置FTP服务器,方便操作服务器文件

    1 进入"控制面板"->"程序"->"打开或关闭Windows功能",找到"Internet信息服务"选项 ...

  8. C语言学生管理系统(原版本)(自编)

    /*系统特色:(大牛勿笑) *颜色提示 *文字提示 *功能 */ #include <stdio.h> #include <stdlib.h> #include <mat ...

  9. TCP协议(二)——TIME_WAIT状态

    当TCP主动关闭套接字时,采用四步握手机制来彻底关闭连接.如图: 客户端主动关闭连接,发送FIN段到服务端.TCP状态由ESTABLISHED(连接状态)转为FIN_WAIT1(表示,发送的FIN需要 ...

  10. zookeeper部署到linux操作步骤

    安装zookeeper1. 上传上传zookeeper,在\01课前资料\02技术资料2. 移动[root@itcast-01 ~]# mv zookeeper-3.4.6.tar.gz /usr/l ...