考研路茫茫——单词情结

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. 【PMP】项目和运营的区别

    运营管理关注产品的持续性生产和服务的持续运作. 项目与运营会存在产品生命周期的不同时点交叉,例如: 在产品开发.产品升级或提高产量时: 在改进运营或产品开发流程时: 在产品生命周期结束阶段: 在每个收 ...

  2. iOS APP 安全测试

    1.ipa包加壳 首先,我们可以通过iTunes 下载 AppStore的ipa文件(苹果 把开发者上传的ipa包 进行了加壳再放到AppStore中),所以我们从AppStore下载的ipa都是加壳 ...

  3. MUI class="mui-switch" 开关 默认为选中

    <label >日期条件: </label> <div id="is_select_time" class="mui-switch mui- ...

  4. ASP.NET Web API(MVC API)

    ASP.NET Web API是​​一个框架,可以很容易构建达成了广泛的HTTP服务客户端,包括浏览器和移动设备.是构建RESTful应用程序的理想平台的.NET框架. 上面是微软对Web API给出 ...

  5. Redis高可用详解:持久化技术及方案选择

    文章摘自:https://www.cnblogs.com/kismetv/p/9137897.html 前言 在上一篇文章中,介绍了Redis的内存模型,从这篇文章开始,将依次介绍Redis高可用相关 ...

  6. 【读书笔记】Data_Mining_with_R---Chapter_2_Predicting Algae Blooms

    本书概要 <Data Mining with R>这本书通过实例,并结合R讲解数据挖掘技术.本书的核心理念就是"Learning it by doing".本书分5章, ...

  7. [docker]使用quaaga实现(rip ospf)实现主机间容器互通

    使用quaaga实现(rip ospf)实现主机间容器互通 - n1设置 brctl addbr br0 ip a a 10.1.1.1/24 br0 ip a a 10.1.1.1/24 dev b ...

  8. 微信小程序场景值

    场景值 基础库 1.1.0 开始支持,低版本需做兼容处理 当前支持的场景值有: 场景值ID 说明 1001 发现栏小程序主入口 1005 顶部搜索框的搜索结果页 1006 发现栏小程序主入口搜索框的搜 ...

  9. [APM] 2个实例+5个维度解读APM技术

    为了加深EGO会员之间的相互了解,同时也为大家提供更多线上相互学习交流的机会,EGO正式启动会员群线上分享活动.本文是根据陈靖华分享主题“APM的价值”的内容整理而成. 第二期分享嘉宾:陈靖华,EGO ...

  10. c++11 输出时间

    C++11中输出当前时间最直接的方法: std::time_t t2 = std::time(nullptr); cout << std::put_time(std::localtime( ...