hdu2243 考研路茫茫——单词情结【AC自动机】【矩阵快速幂】
考研路茫茫——单词情结
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7136 Accepted Submission(s): 2502
一天,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实在是数不出来了,现在就请你帮帮他。
每组数据占两行。
第一行有两个正整数N和L。(0<N<6,0<L<2^31)
第二行有N个词根,每个词根仅由小写字母组成,长度不超过5。两个词根中间用一个空格分隔开。
由于结果可能非常巨大,你只需要输出单词总数模2^64的值。
aa ab
1 2
a
52
题意:
给定$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自动机】【矩阵快速幂】的更多相关文章
- [hdu2243]考研路茫茫——单词情结(AC自动机+矩阵快速幂)
题意:长度不超过L,只由小写字母组成的,至少包含一个词根的单词,一共可能有多少个. 解题关键:利用补集转化的思想,先求一个词根也不包含的单词个数,然后用总的减去即可.长度不超过L需要用矩阵维数增加一倍 ...
- hdu 2243 考研路茫茫——单词情结 ac自动机+矩阵快速幂
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2243 题意:给定N(1<= N < 6)个长度不超过5的词根,问长度不超过L(L <23 ...
- HDU 2243 考研路茫茫——单词情结(AC自动机+DP+快速幂)
题目链接 错的上头了... 这题是DNA的加强版,26^1 +26^2... - A^1-A^2... 先去学了矩阵的等比数列求和,学的是第二种方法,扩大矩阵的方法.剩下就是各种模板,各种套. #in ...
- HDU2243 考研路茫茫——单词情结 ——AC自动机、矩阵优化
题目链接:https://vjudge.net/problem/HDU-2243 考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memor ...
- hdu_2243_考研路茫茫——单词情结(AC自动机+矩阵)
题目链接:hdu_2243_考研路茫茫——单词情结 题意: 让你求包含这些模式串并且长度不小于L的单词种类 题解: 这题是poj2788的升级版,没做过的强烈建议先做那题. 我们用poj2778的方法 ...
- hdu 2243 考研路茫茫——单词情结 AC自动机 矩阵幂次求和
题目链接 题意 给定\(N\)个词根,每个长度不超过\(5\). 问长度不超过\(L(L\lt 2^{31})\),只由小写字母组成的,至少包含一个词根的单词,一共可能有多少个? 思路 状态(AC自动 ...
- HDU-2243 考研路茫茫——单词情结(AC自动机)
题目大意:给n个单词,长度不超过L的单词有多少个包含n个单词中的至少一个单词. 题目分析:用长度不超过L的单词书目减去长度在L之内所有不包含任何一个单词的书目. 代码如下: # include< ...
- hdu 2243 考研路茫茫——单词情结(AC自动+矩阵)
考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
与POJ2778一样.这题是求长度不超过n且包含至少一个词根的单词总数. 长度不超过n的单词总数记为Sn,长度不超过n不包含词根的单词总数记为Tn. 答案就是,Sn-Tn. Sn=26+262+263 ...
随机推荐
- eclipse core expression usage
http://codeandme.blogspot.com/2012/04/expression-examples.html We need to set checkEnabled on the vi ...
- 【PMP】项目的定义和特点
1.定义 项目是为创建独特的产品.服务和成果而进行的的临时性工作. 2.特点 2.1 独特的产品.服务或成果 实现项目目标可能产生一个或多个可交付成果.例如:即便采用相同的材料或者相同的施工单位来建设 ...
- 创建py模板
创建模板之后,每次新建py文件,已初始定义的代码段将会自动出现在py文件中.
- Duplicate Manager Pro for Mac(重复文件查找工具)破解版安装
1.软件简介 Duplicate Manager Pro 是 macOS 系统上一款重复文件查找工具,可以帮你在 Mac 电脑上查找出磁盘上面的重复文件,然后让你对这些重复文件进行判断并删除,使 ...
- 11G新特性 -- ASM Fast Mirror Resync
ASM Fast Mirror Resync 在oracle 10g中,如果asm磁盘因为光纤.控制器发生故障而发生failure,asm将无法继续向该磁盘中写入数据. asm会将发生 ...
- xml解析、写入遇到的坑
前言 最近在看一个线上xml文件导出的问题,需求如下: 从我们平台导出一个后缀为tmx的术语语料数据(实际内容为xml文件),然后导入到其他第三方平台发现无法导入. 从其他平台导入的tmx文件无法导入 ...
- PHP 扩展开发之Zephir
最近对代码进行性能分析后,发现两个耗时的地方:自动加载文件数太多:参数验证函数调用超过1000次.这也是许多php语言框架面临的问题,所以发展出来诸如Yaf,Swoole,Phalcon这些C语言扩展 ...
- Windows 7 设置允许多用户同时远程桌面连接
有时候我们服务器安装的是Win7系统,远程登录桌面时,即使登录的是不同的管理账号,还是会提示把远程登录的人给踢下来.即系统只允许存在一个远程会话窗,不管是不是相同的用户. 下面讲解如何设置Win7让多 ...
- android源码 键盘消息处理机制
键盘消息处理模型: .WMS统一管理Window, 它包含了InputManager变量,其对应c++层的NativeInputManager2.c++层的NativeInputManager包含 i ...
- Socket网络编程--简单Web服务器(1)
这一次的Socket系列准备讲Web服务器.就是编写一个简单的Web服务器,具体怎么做呢?我也不是很清楚流程,所以我找来了一个开源的小的Web服务器--tinyhttpd.这个服务器才500多行的代码 ...