poj 2778 AC自动机+dp矩阵快速幂

CANoe_Demo_下载以及安装教程 CANoe Demo下载安装流程 阅读详情

DNA Sequence
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 12628 Accepted: 4818

Description

It's well known that DNA Sequence is a sequence only contains A, C, T and G, and it's very useful to analyze a segment of DNA Sequence,For example, if a animal's DNA sequence contains segment ATC then it may mean that the animal may have a genetic disease. Until now scientists have found several those segments, the problem is how many kinds of DNA sequences of a species don't contain those segments.

Suppose that DNA sequences of a species is a sequence that consist of A, C, T and G,and the length of sequences is a given integer n.

Input

First line contains two integer m (0 <= m <= 10), n (1 <= n <=2000000000). Here, m is the number of genetic disease segment, and n is the length of sequences.

Next m lines each line contain a DNA genetic disease segment, and length of these segments is not larger than 10.

Output

An integer, the number of DNA sequences, mod 100000.

Sample Input

4 3
AT
AC
AG
AA

Sample Output

36

求长度为n的合法串,假设已经确定了前k个,第k+1个的选择就取决于 前k个是否存在某个后缀是不合法子串的前缀。假设不合法子串是AT,前k个确定了是*****A(最后一个是A),那么第k+1个只能选择C\T\G三种。所以这题的关键是序列的不同后缀之间的状态转移。而字符串间状态的转移就是一个AC自动机状态转移的过程。比如刚刚的情况,假如第k+1个选择了C,那么后缀就是****AC了,这时候考虑AC是不是某个不合法串的前缀,发现不是,则继续考虑后缀C是不是不合法串的前缀,发现也不是则前面的后缀都不需要考虑了,回到初始状态。整个过程和AC自动机匹配字符串的过程是一样的。


#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <set>
using namespace std;

#define maxn 2010
#define mod 100000
typedef long long ll;
typedef vector<ll> vec;
typedef vector<vec> mat;
mat mul(mat &a, mat &b)
{
    mat c(a.size(), vec(b[0].size(),0));
    for(int i=0; i<a.size(); i++)
        for(int j=0; j<b.size(); j++)
        for(int k=0; k<b[0].size(); k++)
        c[i][k]=(c[i][k]+a[i][j]*b[j][k]%mod)%mod;

    return c;
}

int matrix[105][105];

mat pow(mat a, int n)
{
    mat ret(a.size(), vec(a.size(),0));
    for(int i=0; i<ret[0].size(); i++) ret[i][i]=1;

    while(n){
        if(n&1) ret=mul(ret, a);
        a=mul(a,a);
        n>>=1;
    }
    return ret;
}

struct Trie
{
    int next[maxn][4], fail[maxn], endd[maxn],tag[maxn];
    int root, L;
    int newnode()
    {
        for(int i=0; i<4; i++)
            next[L][i]=-1;
        endd[L++]=0;
        return L-1;
    }
    void init()
    {
        L=0;
        root=newnode();
    }

    void insert(char *buf)
    {
        int len=strlen(buf);
        int now=root;
        for(int i=0; i<len ; i++){
            if(next[now][buf[i]-'a']==-1)
                next[now][buf[i]-'a']=newnode();
            now=next[now][buf[i]-'a'];
        }
        endd[now]++;
    }
    int build()
    {
        memset(matrix, 0, sizeof(matrix));
        queue<int> que;
        fail[root]=root;
        int scnt=0;
        tag[root]=scnt++;
        for(int i=0; i<4; i++)
            if(next[root][i]==-1){
                next[root][i]=root;
                matrix[tag[root]][tag[root]]++;
            }
            else if(!endd[next[root][i]]){
                fail[next[root][i]]=root;
                tag[next[root][i]]=scnt++;  
                matrix[tag[root]][tag[next[root][i]]]++;
                que.push(next[root][i]);
            }

        while(!que.empty()){
            int now=que.front(); que.pop();
            for(int i=0; i<4; i++)
                if(next[now][i]==-1){
                    next[now][i]=next[fail[now]][i];
                    if(!endd[next[fail[now]][i]])   //注意后缀节点不合法,则该节点也不合法
                    matrix[tag[now]][tag[next[fail[now]][i]]]++;
                }
                else if(!endd[next[now][i]]){
                    int tmp=fail[next[now][i]]=next[fail[now]][i];
                    if(endd[tmp]){      //注意后缀节点不合法,则该节点也不合法。标记下传
                        endd[next[now][i]]=1;
                        continue;
                    }
                    tag[next[now][i]]=scnt++;
                    matrix[tag[now]][tag[next[now][i]]]++;
                    que.push(next[now][i]);
                }
        }

        return scnt;
    }

};

char buf[100];
void turn(char *buf)
{
    int len=strlen(buf);
    for(int i=0; i<len; i++){
        switch(buf[i])
        {
        case 'A':
            buf[i]='a';
            break;
        case 'G':
            buf[i]='b';
            break;
        case 'C':
            buf[i]='c';
            break;
        case 'T':
            buf[i]='d';
        }
    }
}
Trie trie;
int main()
{
    ll n,m;
    while(cin>>m>>n){
        trie.init();
        for(int i=0; i<m; i++){
            scanf("%s", buf);
            turn(buf);
            trie.insert(buf);
        }
        int scnt=trie.build();
        mat m(scnt, vec(scnt));
        for(int i=0; i<scnt; i++){
            for(int j=0; j<scnt; j++){
            m[i][j]=matrix[i][j];
          //  cout<<matrix[i][j]<<' ';
            }
           // cout<<endl;
        }

        m=pow(m, n);
        mat a(1, vec(scnt,0));
        a[0][0]=1;
        a=mul(a, m);
        ll ans=0;
        for(int i=0; i<a[0].size(); i++)
            ans =(ans+a[0][i])%mod;
        cout<<ans<<endl;

    }

    return 0;
}



【IoT】压力式电子脉搏器设计 智能硬件 阅读详情

相关推荐

【机器人】机械臂控制入门技术栈分享

机械臂控制入门技术栈分享1.前言2.机器人控制入门技术栈2.1.空间描述和变化2.2.运动学分析2.3.动力学建模2.4.控制入门学习3.进阶部分3.1.机器人参数辨识3.2.非线性控制3.3.现代机器人描述方法:指数坐标4.总结 1.前言 今天看到优快云上有个分享个人技术栈的活动,虽然我不是一个正规的程序员,也不搞前端、后端这些,但我一直在优快云上通过写博客对我的学习进行总结,于是我突发奇想,不如我也写一下我的个人技术栈,针对机械臂控制入门的,因为我水平也不高,所以本文内容也许不够饱满,也不够准确,但

要恰饭得嘛 5859

POJ2778-AC自动机,矩阵快速幂优化DP

POJ2778 题目描述 简要题意:给出mmm个病毒串,问你由ATGCATGCATGC构成的长度为 nnn 且不包含这些病毒串的字符串有多少个? 题解 定义dp[i][j]=dp[当前长度为i][当前在AC自动机的第j个节点]=方案数dp[i][j]=dp[当前长度为i][当前在AC自动机的第j个节点]=方案数dp[i][j]=dp[当前长度为i][当前在AC自动机的第j个节点]=方案数. 转移方程也十分简单. 但是注意到nnn的大小,显然会T到飞起,考虑矩阵乘法优化,其实再转化一下题意就是:全图中的000

Daniel__d的博客 301

Python 静态导入与动态导入

python中模块的静态导入 与 动态导入(运行时指定模块),以及具体对应示例。

慢也好,步子小也好,往前走就好~ 717

POJ 2778 DNA Sequence(AC自动机+矩阵快速幂+dp)

大致题意,与之前那道题目差不多,也是由指定的一些字母构成的字符串,不能够包换一些不合法的字符,再告诉你一个长度,问你一共有多少个合法的字符串。但不同的是,这道题目的长度可以很长。 上一道题目,我们介绍了用dp的方法去解决,但是这题面对这么长的长度,显然是不可取的。但是我们回顾一下上一道题目dp的过程,dp[i][j]表示到达AC自动机上的j点走了i步时的方案数,最后要求的是 Σdp[n][j],即到达每个合法点走了n步时的方案数总和。而在图论中,邻接矩阵的乘法、次方,恰好可以表示一个人在图中

alpc_qleonardo 563

iOS In-App Purchase 自动续订订阅完整实现指南

本文摘要: 自动续订订阅是iOS应用变现的核心模式,适用于流媒体、云存储等持续服务场景。文章系统讲解了从配置到实现的完整流程:首先对比各类订阅模式特点,解析订阅生命周期和关键术语;然后详细说明App Store Connect中的订阅组创建、产品配置和服务器通知设置;最后展示客户端StoreKit实现方案,包括产品标识符定义、订阅管理器封装和支付队列观察机制。全文提供可落地的代码示例和技术细节,帮助开发者掌握自动续订订阅的全链路实现。

Sheffi 1760

Spring Boot 3.5.4 + LangChain4j实战:用Milvus搭建企业级RAG问答系统(附阿里百炼API配置)

本文详细介绍了如何利用Spring Boot 3.5.4、LangChain4j与Milvus构建企业级RAG问答系统。内容涵盖从架构设计、阿里百炼API安全配置、Milvus部署优化,到RAG检索、会话管理等核心实现,并提供了生产级API设计、监控集成及性能优化等实战经验,旨在帮助开发者打造高可用、可维护的Java AI应用。

weixin_29054399的博客 610

poj 2778 AC自动机+DP+矩阵快速幂

#include #include #include #include using namespace std; typedef __int64 type; const int kind=4; //每个节点的子节点的个数上限 const int mod = 100000; const int size=109; //转移矩阵的行大小 class AC_auto { public:

Join Hands 2480

【WRF-Chem教程-附录 C】闪电-NOx 参数化方案详解

闪电-NOx 参数化方案详解

WW、forever的博客 974

poj 2778 (AC自动机+dp+矩阵快速幂)

断断续续看了一周AC自动机和Trie图,总算明白一些了,A的不易啊 /* * ===================================================================================== * * Filename: 2778.cpp * Version: 1.0 * Created

__夜 1071

【数字IC刷题】华为海思数字IC笔试题(3)详细解析版

【数字IC刷题】华为海思数字IC笔试题(3)详细解析版

MoorePlus的博客 2370

Level 4自动驾驶系统设计0——功能与场景0

摘要:当前智能驾驶系统开发存在应试思维误区,过度依赖NCAP标准测试而忽视真实物理世界的复杂工况。随着系统进入L4大模型时代,必须从离散测试转向应对无限连续的长尾场景。关键在于解决传感器输入质量(避免"垃圾进垃圾出"问题),通过逆向定义方法论确保前端数据高置信度。同时采用影子模式收集分歧数据流,结合条件接受机制动态调整感知权重,最终实现功能释放主权(FO)的100%安全闭环。本文揭示了如何为端到端智驾大模型建立物理红线,这是确保L4系统量产的底层法则。

Godspeed_zwh的博客 307

poj 2778 ac自动机dp矩阵快速幂

链接http://poj.org/problem?id=2778 题解参考:http://blog.youkuaiyun.com/morgan_xww/article/details/7834801 ch

kdh的专栏 713

Agent应用实践之二十九 - 设计模式:人机协同

本章讲解了一种比较常见的设计模式:人机协同。通过一些场景举例,同时使用AgentScope本身自带的能力实现的人机协同模式,最后通过源码分析了AgentScope中如何实现。通过了解人机协同模式对于实际工程使用也是非常有用的。

代码让AI扣 306

POJ2778 DNA Sequence AC自动机+DP+矩阵快速幂

Problem Address:http://poj.org/problem?id=2778【前言】这道题算是出自Trie主题的。算是一道比较综合的题目。【思路】(1)首先用所给的字符串构造出一个AC自动机。          这一步很简单的,也不多说了。          注意

Human_CK的专栏 914

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

100道动态规划——28 POJ 2778 DNA Sequence AC自动机+DP+矩阵快速幂 很不错嘛

一眼看出是AC自动机上的DP,因为数据量的问题显然不能记忆化搜索或者是递推,然后就不知道怎么做了         天知道还要联系到矩阵快速幂,图论的东西好久都没写过了=_=         定义一个Matrix的数据结构,也就是矩阵,由矩阵的长、宽、以及每个分量上的元素描述而成,支持通常意义上的矩阵乘法(在具体实现的时候用的是稀疏矩阵乘法),此外拥有一个成员函数qpow(int n),返回值为

Sion 792

【POJ 2778 DNA Sequence】 AC自动机+DP+矩阵快速幂

POJ2778 本题题意是给你一个字符集和一个长度m,还有一些敏感串,求出字符集构造出的长度为m的字符串中不包含敏感串的串的个数。 我们用到AC自动机的性质,想象一下如果从len=k向len=k+1转移,AC自动机上每个状态之间有多少种转移方法,就可以构造出对应的转移矩阵,再利用矩阵快速幂就可以求解。在构造转移矩阵的时候,要注意如果某串的后缀是敏感串,也是不可以转移的。 转移矩阵TnTnT^...

lajiyuan的博客 192

POJ 2778 L - DNA Sequence (AC自动机 dp 矩阵快速幂)

It's well known that DNA Sequence is a sequence only contains A, C, T and G, and it's very useful to analyze a segment of DNA Sequence,For example, if a animal's DNA sequence con...

dengyan1183的博客 138

poj 2778 DNA Sequence (ac自动机+矩阵快速幂优化dp)

题目:http://poj.org/problem?id=2778 题意:给出N段DNA序列(仅由‘A’,'T','G','C'四种字符组成),求一段长为L的DNA序列不包含前面给出的任何DNA序列的方案数。 分析:将N个字符串建成ac自动机,然后把所有禁止走的位置标记出来,然后利用ac自动机建二维矩阵Matrix[][],Matrix[u][v]表示节点u走一步到节点v的路径数。然后

w20810的专栏 578

POJ 2778 DNA Sequence ( AC自动机、Trie图、矩阵快速幂、DP )

题意 : 给出一些病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个 分析 : 这题搞了我真特么久啊,首先你需要知道的前置技能包括 AC自动机、构建Trie图、矩阵快速幂,其中矩阵快速幂和AC自动机可能都熟悉,但是这题为什么和矩阵有关系?Trie图是什么呢?好像只听说过Trie树啊!下面我慢慢展开,首先声明本人水平实在实在有限,理解错误的地方请批评指证,万分感激! ...

weixin_30526593的博客 104

poj 2778 DNA Sequence 【ac自动机 + dp + 矩阵快速幂】

这题基本上是纯模版,开始wa了,然后和模版对照了一下,居然是建fail指针的时候搞错了。。。少写了一个q.push(to) #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace st

量子流逝 875

[AC自动机+dp+矩阵快速幂] poj 2778 DNA Sequence

AC自动机+矩阵快速幂经典题,

Enmity_Dark 761

AC自动机+DP(POJ2778&&POJ3691)

AC自动机+DP傻X题

蜜の夜明け 632

POJ 2778 DNA Sequence(AC自动机+矩阵幂DP)

POJ 2778 DNA Sequence(AC自动机+矩阵) http://poj.org/problem?id=2778 题意:所有串只由A,C,T,G字符构成.给你m个模板串,然后给你一个n,问你长为n的由ACTG字符构成的字符串有多少个不包含任意一个模板串.其中n很大. 分析:本题类似于UVA11468: http://blog.youkuaiyun.com/u013480600/articl

code 1439

POJ 2778 (AC自动机+矩阵乘法)

POJ 2778 DNA Sequence Problem : 给m个只含有(A,G,C,T)的模式串(m <= 10, len <=10), 询问所有长度为n的只含有(A,G,C,T)的串中有多少个不含有模式串的串。(n<=2000000000) Solution :首先对所有模式串建立AC自动机。然后dp[i][j]表示长度为i,走到AC自动机的节点j这样的字符串满...

aekijekzn484879763的博客 169

主席树(可持久化线段树)入门专题

1.poj 2104 查询区间第k小。 主席树其实相当于建立了n棵线段树,第i棵线段树是根据区间【1,i】按值建立的。对于每一棵线段树我们记录它对应的区间每个数出现的次数,所以首先要对所有的数离散化。 先考虑最简单的情况,只查询【1,n】的第k小,对于【1,n】我们按值建立一棵线段树,对于a[i]我们在位置a[i]上加1。查询第k小那么先看左子区间出现了多少个数cnt,假设左区间出现的数cnt

写东西的地方 6180
上一篇: hdu 2222 ac自动机模板题
下一篇: poj 1816 Trie+DFS匹配模式串
HuanTongH
博客等级 码龄12年 7粉丝 110原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值