「TJOI2018」str
碱基序列
题目描述
小豆参加了生物实验室。在实验室里,他主要研究蛋白质。他现在研究的蛋白质是由$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
第一个选$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的更多相关文章
- loj2576 「TJOI2018」str
link 题意: 给一个模板串s和n个模式串,每个模式串有$a_i$种可取的串.现在要将n个模式串每个任取一种它可取的串,连接起来,记为串t,那么这种连接方式对答案的贡献为t在s中出现的次数.问所有连 ...
- loj#2574. 「TJOI2018」智力竞赛 (路径覆盖)
目录 题目链接 题解 代码 题目链接 loj#2574. 「TJOI2018」智力竞赛 题解 就是求可重路径覆盖之后最大化剩余点的最小权值 二分答案后就是一个可重复路径覆盖 处理出可达点做二分图匹配就 ...
- 2018.06.26「TJOI2018」数学计算(线段树)
描述 小豆现在有一个数 xxx ,初始值为 111 . 小豆有 QQQ 次操作,操作有两种类型: 111 $ m$ : x=x×mx=x×mx=x×m ,输出 xxx modmodmod MMM : ...
- 【LOJ】#2574. 「TJOI2018」智力竞赛
题解 二分答案 求最小路径点覆盖 由于这里最小路径点覆盖,点是可重的,用floyd求出传递闭包(也就是求出,哪两点之间是可达的) 最后用这个floyd求出的数组建出一个新图,在这个图上跑普通的最小路径 ...
- Loj #3057. 「HNOI2019」校园旅行
Loj #3057. 「HNOI2019」校园旅行 某学校的每个建筑都有一个独特的编号.一天你在校园里无聊,决定在校园内随意地漫步. 你已经在校园里呆过一段时间,对校园内每个建筑的编号非常熟悉,于是你 ...
- LOJ #6436. 「PKUSC2018」神仙的游戏(字符串+NTT)
题面 LOJ #6436. 「PKUSC2018」神仙的游戏 题解 参考 yyb 的口中的长郡最强选手 租酥雨大佬的博客 ... 一开始以为 通配符匹配 就是类似于 BZOJ 4259: 残缺的字符串 ...
- 「HAOI2018」字串覆盖
「HAOI2018」字串覆盖 题意: 给你两个字符串,长度都为\(N\),以及一个参数\(K\),有\(M\)个询问,每次给你一个\(B\)串的一个子串,问用这个字串去覆盖\(A\)串一段区间的最 ...
- 「HAOI2016」字符合并
「HAOI2016」字符合并 题意: 有一个长度为\(n\)的\(01\)串,你可以每次将相邻的\(k\)个字符合并,得到一个新的字符并获得一定分数.得到的新字符和分数由这\(k\)个字符确定.你 ...
- 「 深入浅出 」集合Set
系列文章 「 深入浅出 」集合List 「 深入浅出 」java集合Collection和Map Set继承自Collection接口,不能包含有重复元素.本篇文章主要讲Set中三个比较重要的实现类: ...
随机推荐
- 最新 途牛java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.途牛等10家互联网公司的校招Offer,因为某些自身原因最终选择了途牛.6.7月主要是做系统复习.项目复盘.LeetCode ...
- Python Tkinter 之Listbox控件
Listbox为列表框控件,它可以包含一个或多个文本项(text item),可以设置为单选或多选.使用方式为Listbox(root,option...). 常用的参数列表如下: 一些常用的函数:
- lambda表达式已经成为了开发者必须要掌握的技能?
lambda表达式 lambda表达式是什么 引用百度百科 “Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的la ...
- AOP+Token防止表单重复提交
表单重复提交: 由于用户误操作,多次点击表单提交按钮 由于网速等原因造成页面卡顿,用户重复刷新提交页面 避免表单重复提交的方式: 1.页面上的按钮做防重复点击操作 2.在数据库中可以做唯一约束 3.利 ...
- [转帖]AMD Zen霄龙中国版:海光x86拿下加解密全球第一
AMD Zen霄龙中国版:海光x86拿下加解密全球第一 http://www.eetop.cn/cpu_soc/6946203.html 其实技术发展都是先模仿 剽窃 再自我创新的 要加以鼓励 总比 ...
- 函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!闭包访问局部变量
函数内部声明变量的时候,一定要使用var命令.如果不用的话,你实际上声明了一个全局变量! function f1(){ n=999; } f1(); alert(n); 子函数可以一层一层读取到父元素 ...
- 一行代码让3D翻转后的文本恢复清晰
FlashPlayer10提供的3D功能有一个相当蛋疼的问题:只要设置过rotationX.rotationY或者rotationZ属性,显示对象里面的文字(尤其是设备字体,位图文本)就会一直处于模糊 ...
- Docker3-Dockerfile创建镜像的方法(推荐docker file这种方法)
一.镜像制作的方法 1.本地导入导出镜像 请参考:Docker 架构原理及简单使用 导出:docker save nginx >/tmp/nginx.tar.gz 导入:docker load ...
- Spring Aop中execution的语法
参考地址:https://blog.csdn.net/zz210891470/article/details/54175107 execution(* com.sample.service.impl. ...
- c#的一些书写技巧
从非创建线程访问线程资源 Invoke(new Action<int>((o)=> { textBox1.Text = (Convert.ToInt32(textBox1.Text ...