考研路茫茫——单词情结

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7136    Accepted Submission(s): 2502

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
 
Author
linle
 
Recommend
lcy

题意:

给定$n$个字符串,问长为$l$的串,有多少个里面含有给定的这些字符串之一。

思路:

之前poj2778  https://www.cnblogs.com/wyboooo/p/9899944.html这道题求得是不含有字符串的情况。

那么这道题其实可以转换为,所有的情况减去不含有这些字符串的情况。

建立AC自动机,然后根据标记建立矩阵,矩阵快速幂$l+1$的幂次。

因为长度是小于等于$l$的都行,所以做$l+1$,这里会超$int$

然后对矩阵

$$

\begin{matrix}

26 & 0 \\

1 & 1

\end {matrix}

$$做$l$次快速幂,结果的第二行第一列乘26就是总的个数。

 #include<iostream>
#include<bits/stdc++.h>
#include<cstdio>
#include<cmath>
//#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
//#include<set>
//#include<climits>
//#include<map>
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
#define pi 3.1415926535
#define inf 0x3f3f3f3f const int maxn = ;
struct Tree{
int fail;
int son[];
int ed;
}AC[maxn];
int tot = ; void init()
{
for(int i = ; i <= tot; i++){
AC[i].fail = ;
AC[i].ed = ;
memset(AC[i].son, , sizeof(AC[i].son));
}
tot = ;
} void build(string s)
{
int len = s.length();
int now = ;
for(int i = ; i < len; i++){
if(AC[now].son[s[i] - 'a'] == ){
AC[now].son[s[i] - 'a'] = ++tot;
}
now = AC[now].son[s[i] - 'a'];
}
AC[now].ed += ;
} void get_fail()
{
queue<int>que;
AC[].fail = ;
for(int i = ; i < ; i++){
if(AC[].son[i] != ){
AC[AC[].son[i]].fail = ;
que.push(AC[].son[i]);
}
}
while(!que.empty()){
int u = que.front();
que.pop();
if(AC[AC[u].fail].ed)AC[u].ed++;
for(int i = ; i < ; i++){
if(AC[u].son[i] != ){
AC[AC[u].son[i]].fail = AC[AC[u].fail].son[i];
que.push(AC[u].son[i]);
}
else{
AC[u].son[i] = AC[AC[u].fail].son[i];
}
}
}
} struct matrix{
ull m[maxn][maxn];
int n;
matrix(){}
matrix(int _n)
{
n = _n;
for(int i = ; i < n; i++){
for(int j = ; j < n; j++){
m[i][j] = ;
}
}
}
matrix operator *(const matrix &b)const{
matrix ret = matrix(n);
//memset(ret.m, 0x3f, sizeof(ret.m));
for(int i = ; i < n; i++){
for(int j = ; j < n; j++){
for(int k = ; k < n; k++){
ret.m[i][j] += m[i][k] * b.m[k][j];
}
}
}
return ret;
}
void debug()
{
for(int i = ; i < n; i++){
for(int j = ; j <n; j++){
printf("%llu ", m[i][j]);
}
cout<<endl;
}
}
}g; ull pow_m(ull a, int n)
{
ull ret = ;
ull tmp = a;
while(n){
if(n & )ret *= tmp;
tmp *= tmp;
n >> ;
}
return ret;
} matrix pow_M(matrix a, ull x)
{
//a.debug();
matrix ret = matrix(a.n);
for(int i = ; i < a.n; i++){
ret.m[i][i] = ;
}
matrix tmp = a;
while(x){
if(x & )ret = ret * tmp;
tmp = tmp * tmp;
//tmp.debug();
//ret.debug();cout<<endl;
x >>= ;
}
return ret;
} matrix get_matrix()
{
matrix ret = matrix(tot + );
for(int i = ; i < tot; i++){
if(AC[i].ed)continue;
for(int j = ; j < ; j++){
if(AC[AC[i].son[j]].ed == false){
ret.m[i][AC[i].son[j]]++;
}
}
}
for(int i = ; i < tot + ; i++){
ret.m[i][tot] = ;
}
return ret;
} int n;
ull l;
int main()
{
while(scanf("%d%I64u", &n, &l) != EOF){
init();
for(int i = ; i < n; i++){
string s;
cin>>s;
build(s);
}
//cout<<l<<endl;
get_fail();
g = get_matrix();
//g.debug();
g = pow_M(g, l + );
//g.debug();
ull res = ;
/*for(int i = 0; i < g.n; i++){
res += g.m[0][i];
}*/
res = g.m[][tot] - ;
matrix T = matrix();
//S.m[0][0] = 26;S.m[1][0] = 0;
T.m[][] = ;T.m[][] = ;
T.m[][] = ;T.m[][] = ;
T = pow_M(T, l);
printf("%I64u\n", T.m[][] * - res);
}
return ;
}

hdu2243 考研路茫茫——单词情结【AC自动机】【矩阵快速幂】的更多相关文章

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

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

  2. hdu 2243 考研路茫茫——单词情结 ac自动机+矩阵快速幂

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=2243 题意:给定N(1<= N < 6)个长度不超过5的词根,问长度不超过L(L <23 ...

  3. HDU 2243 考研路茫茫——单词情结(AC自动机+DP+快速幂)

    题目链接 错的上头了... 这题是DNA的加强版,26^1 +26^2... - A^1-A^2... 先去学了矩阵的等比数列求和,学的是第二种方法,扩大矩阵的方法.剩下就是各种模板,各种套. #in ...

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

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

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

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

  6. hdu 2243 考研路茫茫——单词情结 AC自动机 矩阵幂次求和

    题目链接 题意 给定\(N\)个词根,每个长度不超过\(5\). 问长度不超过\(L(L\lt 2^{31})\),只由小写字母组成的,至少包含一个词根的单词,一共可能有多少个? 思路 状态(AC自动 ...

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

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

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

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

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

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

随机推荐

  1. Uber使用Swift重写APP的踩坑经历及解决方案(转载)

    本文出自Uber移动架构和框架组负责人托马斯·阿特曼于2016年在湾区Swift峰会上的演讲,分享了使用Swfit重写Uber的好与坏.以下为译文: 我是托马斯·阿特曼,目前是Uber移动架构和框架组 ...

  2. 如何获取ubuntu源码包里面的源码?

    ubuntu 源仓库说明 1.在获取源码包之前,确保在软件源配置文件/etc/apt/sources.list中添加了deb-src项 vim /etc/apt/sources.list # # de ...

  3. MySQL 5.6新特性 -- Multi-Range Read

    如果基表很大,数据没有被缓存,在二级索引上使用范围扫描读取行可能会导致大量的随机磁盘访问.使用Multi-Range Read新特性,mysql可以减少对磁盘的随机读的次数:首先,mysql只是扫描索 ...

  4. selenium是如何启动浏览器的

    前几天有同学问到selenium是怎么样启动浏览器的(selenium启动浏览器的原理),当时稍微讲解了一下,不过自我感觉不够具体,现在特地把启动原理通过代码和一系列操作给串联起来,希望可以帮助大家更 ...

  5. Python3多线程之间的执行顺序问题

    [本文出自天外归云的博客园] 一个多线程的题:定义三个线程ID分别为ABC,每个线程打印10遍自己的线程ID,按ABCABC……的顺序进行打印输出. 我的解法: from threading impo ...

  6. Go Revel - Cache(缓存)

    revel在服务器端提供了`cache`库用以低延迟的存储临时数据.它缓存那些需要经常访问数据库但是变化不频繁的数据,也可以实现用户会话的存储. ##有效期 一下三种方法为缓存元素设置过期时间: 1. ...

  7. PwniumCTF2014 - JJSN总结

    Write-ups 本文最早发布在TSRC,详细地址:http://security.tencent.com/index.php/blog/msg/55 Forensics USB is FUN 这道 ...

  8. 【转】XML 特殊字符处理

    from: http://gdutlzh.blog.163.com/blog/static/164746951201222934328455/ 1. 在XML文件中,如果内容包含一些特殊字符会导致XM ...

  9. c++ linux socket编程 c++网络编程

    声明:大部分代码来自这篇博客http://www.cnblogs.com/diligenceday/p/6241021.html, 感谢博主 思路: 思路很重要呦~~~ socket详细信息,思路:h ...

  10. 牛客网_Go语言相关练习_选择题(3)

    题目来源于牛客网 一.选择题 Go语言自带垃圾回收机制. 如果是值传递的话子函数对map修改不会影响父函数中的map,如果是地址传递则会影响. go语言编译器会自动在以标识符.数字字面量.字母字面量. ...