考研路茫茫——单词情结

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Problem 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

ac自动机上dp。。。我们才用反向思考,求出没有出现的个数。

dp[i][j] 表示节点 i ,走了 j 步,没有出现的个数。

用矩阵优化 j 这一维就好啦~

但是我们要求了是j 1~L 的前缀和。

所以还有一个矩阵

\[\left[\begin{matrix}
a 1\\
0 1 \\
\end{matrix}\right]
\]

这个就是求前缀和。。。如果是矩阵前缀和就把a换成矩阵,1换成等大小的单位矩阵就好了。


#include<bits/stdc++.h>
#define LL unsigned long long
using namespace std;
const int maxn = 120;
struct lpl{
int n, m;
LL a[maxn][maxn];
}op, bas, ini;
struct ld{int son[30]; int fail; bool f;}node[maxn];
bool vis[30];
int N, L, cnt;
LL all, ans;
char s[maxn]; inline lpl operator * (lpl &A, lpl &B){
lpl ret; ret.n = A.n; ret.m = B.m;
for(int i = 1; i <= ret.n; ++i)
for(int j = 1; j <= ret.m; ++j){
ret.a[i][j] = 0;
for(int k = 1; k <= ret.n; ++k) ret.a[i][j] += A.a[i][k] * B.a[k][j];
}
return ret;
} inline lpl Fpow(lpl A, int t){
lpl ret; lpl tmp = A; ret.n = ret.m = A.n;
memset(ret.a, 0, sizeof(ret.a)); memset(ini.a, 0, sizeof(ini.a));
for(int i = 1; i <= ret.n; ++i) ret.a[i][i] = 1;
while(t){
if(t & 1) ret = ret * tmp;
tmp = tmp * tmp; t >>= 1;
}
return ret;
} inline void putit(){
int len, qwe, now; cnt = 1; memset(node, 0, sizeof(node));
for(int i = 1; i <= N; ++i){
scanf("%s", s + 1); len = strlen(s + 1); now = 1;
for(int j = 1; j <= len; ++j){
qwe = s[j] - 'a' + 1;
if(!node[now].son[qwe]) node[now].son[qwe] = ++cnt;
now = node[now].son[qwe]; if(j == len) node[now].f = true;
}
}
lpl lin; lin.n = lin.m = 2; memset(lin.a, 0, sizeof(lin.a));
lin.a[1][1] = 26; lin.a[1][2] = lin.a[2][2] = 1;
lin = Fpow(lin, L); all = lin.a[1][1] + lin.a[1][2] - 1;
} inline void AC(){
queue<int> q; queue<int> qqq;
q.push(1); qqq.push(1);
while(!q.empty()){
int now = q.front(); q.pop();
for(int i = 1; i <= 26; ++i){
if(!node[now].son[i]) continue;
q.push(node[now].son[i]); qqq.push(node[now].son[i]);
if(now == 1){node[node[now].son[i]].fail = 1; continue;}
int t = node[now].fail;
while(!node[t].son[i] && t) t = node[t].fail;
if(!t) node[node[now].son[i]].fail = 1;
else node[node[now].son[i]].fail = node[t].son[i];
}
}
while(!qqq.empty()){
int now = qqq.front(); qqq.pop();
int qwe = now;
while(qwe){
if(node[qwe].f){node[now].f = true; break;}
qwe = node[qwe].fail;
}
}
} inline void workk(){
op.n = cnt, op.m = 1; memset(op.a, 0, sizeof(op.a)); op.a[1][1] = 1;
memset(bas.a, 0, sizeof(bas.a)); bas.n = bas.m = cnt;
for(int i = 1; i <= cnt; ++i){
int now = i, lft = 26; memset(vis, false, sizeof(vis));
while(now){
for(int j = 1; j <= 26; ++j){
if(!node[now].son[j]) continue;
if(!vis[j]){
vis[j] = true; lft--;
bas.a[node[now].son[j]][i] = 1;
}
}
now = node[now].fail;
}
bas.a[1][i] = lft;
}
for(int i = 1; i <= cnt; ++i)
if(node[i].f)
for(int j = 1; j <= cnt; ++j) bas.a[i][j] = 0;
ini.n = ini.m = cnt * 2;
for(int i = 1; i <= cnt; ++i){
ini.a[i][i + cnt] = ini.a[i + cnt][i + cnt] = 1;
for(int j = 1; j <= cnt; ++j) ini.a[i][j] = bas.a[i][j];
}
ini = Fpow(ini, L);
for(int i = 1; i <= cnt; ++i)
for(int j = 1; j <= cnt; ++j){
bas.a[i][j] = ini.a[i][j] + ini.a[i][j + cnt];
if(i == j) bas.a[i][j]--;
}
op = bas * op; ans = 0;
for(int i = 1; i <= cnt; ++i) ans += op.a[i][1];
ans = all - ans;
cout << ans << endl;
} int main()
{
while(~scanf("%d%d", &N, &L)){
putit();
AC();
workk();
}
return 0;
}

hud2243 考研路茫茫——单词情结的更多相关文章

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

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

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

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

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

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

  4. hdu2243 考研路茫茫——单词情结【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. HDU2243 考研路茫茫——单词情结 ——AC自动机、矩阵优化

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

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

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

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

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

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

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

随机推荐

  1. AOP切面详解

    一.spring-aop.xml文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns= ...

  2. java并发学习--第一章 线程的创建

    所谓的并发就是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行.所以我们看似几个线程在同时进行,其实在操作系统中 ...

  3. CSS3 nth-of-type(n)选择器 last-of-type选择器 nth-last-of-type(n)选择器 CSS3 only-child选择器 only-of-type选择器

    CSS3 nth-of-type(n)选择器 “:nth-of-type(n)”选择器和“:nth-child(n)”选择器非常类似,不同的是它只计算父元素中指定的某种类型的子元素.当某个元素中的子元 ...

  4. 《Webkit技术内幕》之页面渲染过程

    文章同步到github<Webkit技术内幕>之页面渲染过程 最近拜读了传说中的<Webkit技术内幕>一书,有很大收获,尤其是对页面渲染有了较深的认识.由于功力有限,而且书中 ...

  5. final、finally、 finalize区别

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11444366.html final final可以用来修饰类.方法.变量,分别有不同的意义,final ...

  6. CUDA Error

    第一个问题:CUDA Error: out of memory darknet: ./src/cuda.c:36: check_error: Assertion `0' failed. 已放弃 (核心 ...

  7. UI定位元素大全(跟App定位元素差不多哦)

    selenium+python自动化之元素定位 作者:一飞冲天 同样的道理,把一个页面上的元素当成是一个对象(你的女神),我们就可以通过她的属性值来找到她,比如她性别女爱好爬山---------你就可 ...

  8. Flink 在人工智能领域的应用实践

    人工智能是未来十年最重要的技术革命与驱动力,在各行各业产生着日益重要的作用,它与大数据的发展相辅相成,不仅推动人类社会迈入更智慧的世界,也为数据的应用带来无可估量的价值. 11 月 28 - 30 日 ...

  9. Java学习、面试、求职、干货资源精品合集

    本系列文章整合了本号发表和转载过的,有关Java学习.进阶.面试.做项目.求职经验等方面的文章,希望对想要找工作,以及正在找工作的你,能够有所帮助. 原创Java学习专题文章: 如何才能够系统地学习J ...

  10. LintCode之加一

    题目描述: 分析:由样例可以知道,当数组的每一个数字都是9时,加一会产生一个最高位的数字1,所以先判断这个数组的每一位是否都是9,如果是,那么新数组的大小是原数组大小加一,否则新数组的大小等于原数组的 ...