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 ...
随机推荐
- JS获取短信验证码60秒
<script language="javascript"> function get_mobile_code(){ $.post("{{ ...
- 【生产问题】--8KW的数据表导致业务卡顿
问题描述:业务突然变得巨卡 分析思路: (1)分析用户请求进程:查看是否有长期运行霸占锁的情况,或者进程数量巨多.很明显我这里就是巨多,正常情况一般0~40来个的样子,在业务使用高峰期居然达到了140 ...
- Java基础—反射(转载)
转载自: JAVA反射与注解 JAVA反射 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 反射机制是什么 反射 ...
- Python基础-os和sys模块
os模块提供对操作系统进行调用的接口 import os os.getcwd() # 获取当前工作目录 os.chdir(r'd:\fansik') # 修改对当前工作目录 print(os.curd ...
- ACM解题之(ZOJ 2724)Windows Message Queue
题目来源: 点击打开链接 题目翻译: 消息队列是windows系统的基本基础.对于每个进程,系统都维护一个消息队列.如果这个过程发生某些事情,例如鼠标点击,文本改变,系统会向队列添加一条消息.同时,如 ...
- 算法题16 贪吃的小Q 牛客网 腾讯笔试题
算法题16 贪吃的小Q 牛客网 腾讯笔试题 题目: 链接:https://www.nowcoder.com/questionTerminal/d732267e73ce4918b61d9e3d0ddd9 ...
- oracle 函数 截取 连接 替换 判断
一个处理不规范日期的函数,廖记一下吧,以免再忘. --注意全角半角 CREATE OR REPLACE function f_str2form( date_string in varchar2 ) r ...
- php大转盘抽奖
抽奖大转盘演示:http://www.sucaihuo.com/php/3301.html function getRand($proArr, $proCount) { $result = ''; $ ...
- 定制AIX操作系统的shell环境
操作系统与外部最主要的接口就叫做shell.shell是操作系统最外面的一层.shell管理你与操作系统之间的交互:等待你输入,向操作系统解释你的输入,并且处理各种各样的操作系统的输出结果. shel ...
- ETL应用:使用Pro*C写入文件信息入库的方法
ETL处理过程中,经常需要进行文件校验,如文件级校验.记录级校验,需要保存文件的基本信息,文件名.文件大小.数据日期等,使用Pro*C的一种方法如下: #include <stdio.h> ...