碱基序列

题目描述

小豆参加了生物实验室。在实验室里,他主要研究蛋白质。他现在研究的蛋白质是由$k$个氨基酸按一定顺序构成的。每一个氨基酸都可能有$a$种碱基序列$s_{i,j}$构成。

现在小豆有一个碱基串$s$,小豆想知道在这个碱基上都多少中不同的组合方式可能得到这个蛋白质。即求由$k$段字符串有序合并成的字符串$s_1$,有多少种不同方式能够匹配字符串$s$,其中$k$段字符串的选法不同,或者与$s$匹配上的位置不同认为是不同的方式。

输入输出格式

输入格式:

第一行一个数,表示这个蛋白质由$k$个氨基酸。

第二行一个字符串$s$,表示小豆现在有的碱基串。

第三行开始接下来$k$行表示第$i$个氨基酸可能的碱基序列,对于第$i$个氨基酸,$a_i$表示这个氨基酸可能的碱基序列种数,接下来$a_i$个字符串表示这$a_i$种可能的碱基序列,用空格隔开。

输出格式:

输出一个数目标是不同的方案数(不同的方案数是指不同的子碱基串或者相同的碱基串不同的氨基酸排列方式)

答案对$10^9+7$取模

输入输出样例

输入样例#1:
复制

2
ABC
2 A AB
2 C BC
输出样例#1:
复制

2
输入样例#2:
复制

2
AAA
2 A AA
2 A AA
输出样例#2:
复制

4

说明

样例解释1

第一个选$A$第二个选$C$,得到$AC$能够与$ABC$产生$0$中匹配方式

第一个选$A$第二个选$BC$,得到$ABC$能够与$ABC$产生$1$中匹配方式

第一个选$AB$第二个选$C$,得到$ABC$能够与$ABC$产生$1$中匹配方式

第一个选$AB$第二个选$BC$,得到$ABBC$能够与$ABC$产生$0$中匹配方式

所以一共2种

样例解释2

第一个选$A$第二个选$A$,得到$AA$能够与$AAA$产生$2$中匹配方式

第一个选$A$第二个选$AA$,得到$AAA$能够与$AAA$产生$1$中匹配方式

第一个选$AA$第二个选$A$,得到$AAA$能够与$AAA$产生$1$中匹配方式

第一个选$AA$第二个选$AA$,得到$AAAA$能够与$AAA$产生$0$中匹配方式

所以一共4种

数据范围

对于$30\%$的数据,$1\leq k\leq25,|s|\leq10000,a_i\leq3$

对于$100\%$的数据,$1\leq k\leq100,|s|\leq10000,a_i\leq10$

题解

参照bestfy的题解。

设f[i][j]表示使用前i个模式串,匹配前j位的贡献。对每个模式串的每种可能转移,使用hash判断是否匹配。

复杂度O(|S|×∑ai)。

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;rg char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std; co int N=1e4+2,P=131,mod=1e9+7;
il int add(int x,int y) {return (x+=y)>=mod?x-mod:x;}
il int mul(int x,int y) {return (ll)x*y%mod;}
int m,n,h[N],p[N];
char s[N];
il int calc(int l,int r){
return add(h[r],mod-mul(h[l-1],p[r-l+1]));
}
int now,f[2][N]; int main(){
read(m);
scanf("%s",s+1),n=strlen(s+1);
p[0]=1;
for(int i=1;i<=n;++i){
p[i]=mul(p[i-1],P);
h[i]=add(mul(h[i-1],P),s[i]);
}
fill(f[0],f[0]+n+1,1);
while(m--){
now^=1,fill(f[now],f[now]+n+1,0); // edit 1:clear from 0
for(int a=read<int>(),l;a--;){
scanf("%s",s+1),l=strlen(s+1);
int hash=0;
for(int i=1;i<=l;++i) hash=add(mul(hash,P),s[i]);
for(int i=1;i<=n-l+1;++i)if(calc(i,i+l-1)==hash)
f[now][i+l-1]=add(f[now][i+l-1],f[now^1][i-1]);
}
}
int ans=0;
for(int i=1;i<=n;++i) ans=add(ans,f[now][i]);
printf("%d\n",ans);
return 0;
}

「TJOI2018」str的更多相关文章

  1. loj2576 「TJOI2018」str

    link 题意: 给一个模板串s和n个模式串,每个模式串有$a_i$种可取的串.现在要将n个模式串每个任取一种它可取的串,连接起来,记为串t,那么这种连接方式对答案的贡献为t在s中出现的次数.问所有连 ...

  2. loj#2574. 「TJOI2018」智力竞赛 (路径覆盖)

    目录 题目链接 题解 代码 题目链接 loj#2574. 「TJOI2018」智力竞赛 题解 就是求可重路径覆盖之后最大化剩余点的最小权值 二分答案后就是一个可重复路径覆盖 处理出可达点做二分图匹配就 ...

  3. 2018.06.26「TJOI2018」数学计算(线段树)

    描述 小豆现在有一个数 xxx ,初始值为 111 . 小豆有 QQQ 次操作,操作有两种类型: 111 $ m$ : x=x×mx=x×mx=x×m ,输出 xxx modmodmod MMM : ...

  4. 【LOJ】#2574. 「TJOI2018」智力竞赛

    题解 二分答案 求最小路径点覆盖 由于这里最小路径点覆盖,点是可重的,用floyd求出传递闭包(也就是求出,哪两点之间是可达的) 最后用这个floyd求出的数组建出一个新图,在这个图上跑普通的最小路径 ...

  5. Loj #3057. 「HNOI2019」校园旅行

    Loj #3057. 「HNOI2019」校园旅行 某学校的每个建筑都有一个独特的编号.一天你在校园里无聊,决定在校园内随意地漫步. 你已经在校园里呆过一段时间,对校园内每个建筑的编号非常熟悉,于是你 ...

  6. LOJ #6436. 「PKUSC2018」神仙的游戏(字符串+NTT)

    题面 LOJ #6436. 「PKUSC2018」神仙的游戏 题解 参考 yyb 的口中的长郡最强选手 租酥雨大佬的博客 ... 一开始以为 通配符匹配 就是类似于 BZOJ 4259: 残缺的字符串 ...

  7. 「HAOI2018」字串覆盖

    「HAOI2018」字串覆盖 题意: ​ 给你两个字符串,长度都为\(N\),以及一个参数\(K\),有\(M\)个询问,每次给你一个\(B\)串的一个子串,问用这个字串去覆盖\(A\)串一段区间的最 ...

  8. 「HAOI2016」字符合并

    「HAOI2016」字符合并 题意: ​ 有一个长度为\(n\)的\(01\)串,你可以每次将相邻的\(k\)个字符合并,得到一个新的字符并获得一定分数.得到的新字符和分数由这\(k\)个字符确定.你 ...

  9. 「 深入浅出 」集合Set

    系列文章 「 深入浅出 」集合List 「 深入浅出 」java集合Collection和Map Set继承自Collection接口,不能包含有重复元素.本篇文章主要讲Set中三个比较重要的实现类: ...

随机推荐

  1. redis示例

    1. 引入redis相关包 <!-- redis 相关包--> <dependency> <groupId>org.springframework.data< ...

  2. 【转帖】编译-O 选项对性能提升作用

    编译-O 选项对性能提升作用 https://www.cnblogs.com/pigerhan/p/3526889.html GCC -O 选项 这个选项控制所有的优化等级.使用优化选项会使编译过程耗 ...

  3. MySQL必知必会2

    使用数据处理函数 函数 与其他大多数计算机语言一样,SQL支持利用函数来处理数据.函数一般是在数据上执行的,他给数据的转换和处理提供了方便,在前一章中用来去掉尾空格的RTrim()就是一个函数的例子 ...

  4. SpringMVC笔记1

    SpringMVC是一个一种基于Java的实现MVC设计模型的请求驱动类型的轻量级web框架 SpringMVC的入门案例 2.导入相关jar包 <?xml version="1.0& ...

  5. flask框架(四)——flask CBV视图类解析

    CBV视图类的两种基本写法 #第一种写法class IndexView(views.View): methods = ['GET'] decorators = [auth, ] def dispatc ...

  6. typescript之基础类型

    基础类型分为:数字.字符串.数组.元组.枚举.Any.Object.Null.Undefined.Never.Void 各种类型写法如下: 1.数字(number) let num:number = ...

  7. Spring主要用到两种设计模式

    Spring主要用到两种设计模式 1.工厂模式 Spring容器就是实例化和管理全部Bean的工厂. 工厂模式可以将Java对象的调用者从被调用者的实现逻辑中分离出来. 调用者只关心被调用者必须满足的 ...

  8. C# 文件类中 File ,FileInfo 类的主要区别

    System.IO命名空间中提供的文件操作类有File和FileInfo,这两个类的功能基本相同,只是File是静态类,其中所有方法都是静态的,可以通过类名直接调用,不需要实例化.而FileInfo是 ...

  9. 后台传带引号(")的数据需要注意

    后台返回给前端的json字符串 [{"\"Name\":\"<span style=\\\"color: red\\\">&qu ...

  10. vmware的三种网络模式讲解

    vmware有三种网络设置模式,分别是Bridged(桥接),NAT(网络地址转换),Host-only(私有网络共享主机) 1.Bridged(桥接) 桥接模式默认使用的是:VMnet0 什么是桥接 ...