hdu2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
来源:互联网 发布:sql sum over 用法 编辑:程序博客网 时间:2024/05/18 01:30
题目链接:点击打开链接
题目描述:给定一些词根,求至少含有一个词根的长度<=L的字符串有多少种?
解题思路:AC自动机+矩阵快速幂
分析:这道题目和poj2778 DNA Sequence 是一样的,如果还没做过那道题目建议先去做一下再做这道
1、首先要知道图的邻接矩阵幂的含义是什么?不知道的请看:点击打开链接
有了上述概念之后:
AC自动机本身就是一张图,AC自动机上的每个状态表示图中的一个顶点,每条经过a、b、c···的状态转移相当于图中的一条边,所以求长度为n的字符串就相当于求在图中从出发点经过n步所能到达任意顶点的方案总数,而本题所要求的是<=L的,我们只需要求邻接矩阵A的A^1+A^2+···+A^n的方案数即可
关于如何求包含词根的字符串,根据poj2778我们会求解不包含词根的字符串,只要用总的减去不包含的就可以了即:(26^1+26^2+···+26^n)-(A^1+A^2+···+A^n)
对于如何求解一个数的前n次幂的和与一个矩阵的前n次幂的和,我们可以使用矩阵快速幂
譬如:26^1+26^2+···+26^n
|1 26| |0|
|0 26| |1|
A^1+A^2+···+A^n
|E A| |0|
|0 A| |E|
代码如下:
#include <cstdio>#include <cstring>#include <queue>typedef unsigned long long ll;using namespace std;struct Matrix{ ll m[60][60]; int L; Matrix(int len){ L=len; for(int i=0;i<L;++i) for(int j=0;j<L;++j) m[i][j]=0; } Matrix operator*(const Matrix& b){ Matrix t(L); for(int i=0;i<L;++i) for(int j=0;j<L;++j) for(int k=0;k<L;++k) t.m[i][j]+=(m[i][k]*b.m[k][j]); return t; }};Matrix doexpmat(Matrix a,int num){ if(num==1) return a; Matrix x(a.L*2); for(int i=0;i<a.L;++i) for(int j=0;j<a.L;++j) if(i==j)x.m[i][j]=1; for(int i=a.L;i<x.L;++i) for(int j=0;j<a.L;++j) x.m[i][j]=0; for(int i=0;i<a.L;++i) for(int j=a.L;j<x.L;++j) x.m[i][j]=a.m[i][j-a.L]; for(int i=a.L;i<x.L;++i) for(int j=a.L;j<x.L;++j) x.m[i][j]=a.m[i-a.L][j-a.L]; Matrix t(a.L*2); for(int i=0;i<t.L;++i) t.m[i][i]=1; num--; while(num){ if(num&1) t=t*x; num=num>>1; x=x*x; } Matrix tt(a.L*2); for(int i=0;i<a.L;++i) for(int j=0;j<a.L;++j) tt.m[i][j]=a.m[i][j]; for(int i=a.L;i<t.L;++i) for( int j=0;j<a.L;++j) tt.m[i][j]=a.m[i-a.L][j]; t=t*tt; return t;}ll pows(ll a,int num){ if(num==1) return a; Matrix x(2); x.m[0][0]=1; x.m[0][1]=a; x.m[1][0]=0; x.m[1][1]=a; Matrix t(2); t.m[0][0]=1; t.m[1][1]=1; num--; while(num){ if(num&1) t=t*x; num=num>>1; x=x*x; } return (t.m[0][0]+t.m[0][1])*a;}struct Trie{ int next1[30][26],fail[30]; bool end1[30]; int root,L; int newnode(){ for(int i=0;i<26;++i) next1[L][i]=-1; end1[L++]=false; return L-1; } void init(){ L=0; root=newnode(); } void insertnode(char* str){ int len=strlen(str),now=root; for(int i=0;i<len;++i){ if(next1[now][str[i]-'a']==-1) next1[now][str[i]-'a']=newnode(); now=next1[now][str[i]-'a']; } end1[now]=true; } void build(){ fail[root]=root; queue<int> q; for(int i=0;i<26;++i){ if(next1[root][i]==-1) next1[root][i]=root; else{ fail[next1[root][i]]=root; q.push(next1[root][i]); } } while(!q.empty()){ int now=q.front();q.pop(); if(end1[fail[now]]) end1[now]=true; for(int i=0;i<26;++i){ if(next1[now][i]==-1) next1[now][i]=next1[fail[now]][i]; else{ fail[next1[now][i]]=next1[fail[now]][i]; q.push(next1[now][i]); } } } } Matrix getMatrix(){ Matrix t(L); for(int i=0;i<L;++i) for(int j=0;j<26;++j) if(!end1[next1[i][j]]) t.m[i][next1[i][j]]++; return t; }};int n,l;char st[10];Trie ac;int main(){ while(scanf("%d%d",&n,&l)!=EOF){ ac.init(); for(int i=0;i<n;++i){ scanf("%s",st); ac.insertnode(st); }; ac.build(); Matrix t = ac.getMatrix(); t=doexpmat(t,l); ll ans=0; for(int i=0;i<ac.L;++i) ans+=t.m[0][i]; ll tmp=pows(26,l); printf("%I64u\n",tmp-ans); } return 0;}
0 0
- hdu2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
- HDU2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂+等比矩阵求和)
- hdu2243 考研路茫茫——单词情结 AC自动机+矩阵快速幂
- hdu2243 考研路茫茫——单词情结 (AC自动机+矩阵快速幂)
- 【hdu2243】【AC自动机】【矩阵乘法】考研路茫茫——单词情结
- HDU2243 考研路茫茫——单词情结 AC自动机DP矩阵优化
- hdu2243---考研路茫茫——单词情结(AC自动机+矩阵+二分)
- HDU2243 考研路茫茫——单词情结 AC自动机+矩阵连乘
- HDU 2243 考研路茫茫——单词情结 (AC自动机+矩阵快速幂求和)
- HDU 2243 考研路茫茫——单词情结 (AC自动机 + 矩阵快速幂)
- HDU 2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
- HDOJ 2243 考研路茫茫——单词情结 AC自动机+矩阵快速求幂和
- hdu 2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
- HDOJ 2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
- HDU 2243 考研路茫茫——单词情结 AC自动机 + 矩阵快速幂
- hdu 2433 考研路茫茫——单词情结 ac自动机+矩阵快速幂+dp
- HDU2243 考研路茫茫――单词情结 AC自动机
- HDU 2243 考研路茫茫――单词情结 (AC自动机 + 矩阵快速幂)
- hdu1078+FatMouse and Cheese+DFS+记忆化搜索
- When Weaker is Better: Understanding Soft, Weak and Phantom References
- 互联网思维PK大数据思维
- 解决Studio运行出现Failure [INSTALL_FAILED_OLDER_SDK]
- 使用Eclipse中提供的Refactor(重构)工具
- hdu2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
- django_学习笔记0903
- 黑马程序员——Java基础之网络编程
- Java 基础笔记之二 变量和常量有什么区别
- uva 11137 - Ingenuous Cubrency 立方数之和 递推
- Struts2 概述:Action中获取Request
- Active Network 活跃网络 面试
- 初学者应该解决的设计模式面试问题
- 1210 - Sum of Consecutive Prime Numbers(数学水题)