poj2778 ac自动机+矩阵快速幂
给m个子串,求长度为n的不包含子串的母串数,最直接的应该是暴搜,肯定tle,考虑用ac自动机
将子串建成字典树,通过next表来构造矩阵,然后用矩阵快速幂求长度为n的数量
邻接矩阵https://wenku.baidu.com/view/d7b9787f1711cc7931b716b0.html
对于a(i,j)^k 是指从i到j经过k个点的所有情况数
注意对于End数组,如果某个节点如果fail指针End数组为1,那么End【该节点】也是1
string要开全局变量,不然不能运行= =
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<iomanip>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define C 0.5772156649
#define pi acos(-1.0)
#define ll long long
#define mod 100000
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1 using namespace std; const double g=10.0,eps=1e-;
const int N=+,maxn=+,inf=0x3f3f3f; struct Node{
int len;
ll a[N][N];
};
Node mul(Node x,Node y)
{
Node ans;
ans.len=x.len;
memset(ans.a,,sizeof ans.a);
for(int i=;i<x.len;i++)
for(int j=;j<x.len;j++)
for(int k=;k<y.len;k++)
ans.a[i][k]=(ans.a[i][k]+x.a[i][j]*y.a[j][k])%mod;
return ans;
}
Node quick_mul(Node x,int n)
{
Node ans;
ans.len=x.len;
memset(ans.a,,sizeof ans.a);
for(int i=;i<ans.len;i++)ans.a[i][i]=;
while(n)
{
if(n&)ans=mul(ans,x);
x=mul(x,x);
n/=;
}
return ans;
}
struct Trie{
int tot,root;
int Next[N][],fail[N];
bool End[N];
int change(char s)
{
if(s=='A')return ;
else if(s=='C')return ;
else if(s=='T')return ;
else return ;
}
int newnode()
{
for(int i=;i<;i++)
Next[tot][i]=-;
End[tot]=;
return tot++;
}
void init()
{
tot=;
root=newnode();
}
void insertstring(string s)
{
int now=root;
for(int i=;i<s.size();i++)
{
if(Next[now][change(s[i])]==-)
Next[now][change(s[i])]=newnode();
now=Next[now][change(s[i])];
}
End[now]=;
}
void build()
{
queue<int>q;
fail[root]=root;
for(int i=;i<;i++)
{
if(Next[root][i]==-)Next[root][i]=root;
else
{
fail[Next[root][i]]=root;
q.push(Next[root][i]);
}
}
while(!q.empty())
{
int now=q.front();
q.pop();
if(End[fail[now]])End[now]=;
for(int i=;i<;i++)
{
if(Next[now][i]==-)Next[now][i]=Next[fail[now]][i];
else
{
fail[Next[now][i]]=Next[fail[now]][i];
q.push(Next[now][i]);
}
}
}
}
int solve(int n)
{
Node ans;
ans.len=tot;
memset(ans.a,,sizeof ans.a);
for(int i=;i<tot;i++)
for(int j=;j<;j++)
if(!End[Next[i][j]])
ans.a[i][Next[i][j]]++;
ans=quick_mul(ans,n);
int res=;
for(int i=;i<ans.len;i++)
res=(res+(int)ans.a[][i])%mod;
return res;
}
};
Trie ac;
string s;
int main()
{
ios::sync_with_stdio(false);
cin.tie();
int n,m;
while(cin>>m>>n)
{
ac.init();
for(int i=;i<m;i++)
{
cin>>s;
ac.insertstring(s);
}
ac.build();
cout<<ac.solve(n)<<endl;
}
return ;
}
/******************** ********************/
poj2778 ac自动机+矩阵快速幂的更多相关文章
- POJ2778 DNA Sequence(AC自动机+矩阵快速幂)
题目给m个病毒串,问不包含病毒串的长度n的DNA片段有几个. 感觉这题好神,看了好久的题解. 所有病毒串构造一个AC自动机,这个AC自动机可以看作一张有向图,图上的每个顶点就是Trie树上的结点,每个 ...
- POJ2778(SummerTrainingDay10-B AC自动机+矩阵快速幂)
DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17160 Accepted: 6616 Des ...
- poj2778DNA Sequence (AC自动机+矩阵快速幂)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud DNA Sequence Time Limit: 1000MS Memory ...
- HDU 2243考研路茫茫——单词情结 (AC自动机+矩阵快速幂)
背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...
- HDU 2243 考研路茫茫――单词情结 ——(AC自动机+矩阵快速幂)
和前几天做的AC自动机类似. 思路简单但是代码200余行.. 假设solve_sub(i)表示长度为i的不含危险单词的总数. 最终答案为用总数(26^1+26^2+...+26^n)减去(solve_ ...
- POJ - 2778 ~ HDU - 2243 AC自动机+矩阵快速幂
这两题属于AC自动机的第二种套路通过矩阵快速幂求方案数. 题意:给m个病毒字符串,问长度为n的DNA片段有多少种没有包含病毒串的. 根据AC自动机的tire图,我们可以获得一个可达矩阵. 关于这题的t ...
- 考研路茫茫——单词情结 HDU - 2243 AC自动机 && 矩阵快速幂
背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...
- POJ 2778 DNA Sequence(AC自动机 + 矩阵快速幂)题解
题意:给出m个模式串,要求你构造长度为n(n <= 2000000000)的主串,主串不包含模式串,问这样的主串有几个 思路:因为要不包含模式串,显然又是ac自动机.因为n很大,所以用dp不太好 ...
- hdu 2243 考研路茫茫——单词情结 ac自动机+矩阵快速幂
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2243 题意:给定N(1<= N < 6)个长度不超过5的词根,问长度不超过L(L <23 ...
随机推荐
- TypeError: save() missing 1 required positional argument: 'self'
RT,在创建模型对象的时候,提示TypeError: save() missing 1 required positional argument: 'self' 解决办法:在创建模型对象的时候需要加上 ...
- docker介绍和简单使用
docker介绍 docker 为什么会有docker出现? 一款产品从开发到上线,从操作系统到运行环境,再到应用配置,作为开发+运维直接的协作我们需要关心很多东西,这也是互联网公司不得 不面对问题, ...
- Python判断网络是否可以访问
import urllib url = "http://www.baidu.com" try: status = urllib.urlopen(url).code print st ...
- Linux中的日志功能
配置文件 /etc/logrotate.conf daily 日志的轮替周期是每天weekly 日志的轮替周期是每周monthly 日志的轮替周期是每月rotate 数字 保留的日志文件的个数comp ...
- C#数组存入引用类型
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cont ...
- 自制Javascript浮动广告
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb ...
- uuid的使用
1.mysql中直接使用uuid()函数,可以生成一个随机的uuid 正常的uuid是36位长度的,其中有4个字符是‘-’,在mysql中可以使用replace()函数来替换‘-’ insert in ...
- 【转】Linux查看物理CPU个数、核数、逻辑CPU个数
# 总核数 = 物理CPU个数 X 每颗物理CPU的核数 # 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数 # 查看物理CPU个数cat /proc/cpuinfo| g ...
- SOA宣言和微服务特点
如果从概念层来看,我更喜欢把SOA归为企业架构的范畴,从企业架构出发把业务分解为不同业务域的服务,关注系统间的服务互联互通的规范,并不关心如何实现.也就是说在企业架构上使用SOA支撑业务,而在方案架构 ...
- Win32 API编程:WinMain无法重载函数或_tWinMain无法重载
#include "windows.h" #include "tchar.h" int APIENTRY _tWinMain( HINSTANCE hInsta ...