洛谷3763:[TJOI2017]DNA——题解
https://www.luogu.org/problemnew/show/P3763
加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其中不超过3个碱基,依然能够表现出吃藕的性状。现在研究人员想知道这个基因在DNA链S0上的位置。所以你需要统计在一个表现出吃藕性状的人的DNA序列S0上,有多少个连续子串可能是该基因,即有多少个S0的连续子串修改小于等于三个字母能够变成S。
是的这篇代码过不了BZOJ(因为懒得卡了/不想写SAM/不会DC3……众多原因)
其实容错三次匹配并不吓人,我们可以先跳跃匹配到匹配不上的地方,然后cnt++,继续跳跃……直到匹配完全或者cnt>3为止。
这个跳跃完全可以枚举起点,然后用SA来求lcp进而实现跳跃匹配以此变成$O(n)$的。
所以总复杂度是$O(Tnlogn)$的……只要卡卡就能过洛谷。
当然为了过BZOJ,要么常数优秀(写SAM,然后遍历,每次选择一个节点往下走,如果和当前节点匹配不上则cnt++,匹配复杂度不变但是常数小),要么就学DC3,要么……其实后缀数组卡卡也能过。
- #include<map>
- #include<cmath>
- #include<stack>
- #include<queue>
- #include<cstdio>
- #include<cctype>
- #include<vector>
- #include<cstdlib>
- #include<cstring>
- #include<iostream>
- #include<algorithm>
- using namespace std;
- typedef long long ll;
- const int N=2e5+;
- inline int turn(char ch){
- if(ch==)return ;
- if(ch=='A')return ;
- if(ch=='G')return ;
- if(ch=='C')return ;
- if(ch=='T')return ;
- return ;
- }
- char s[N],p[N];
- int n,rk[N],height[N],w[N],sa[N];
- inline bool pan(int *x,int i,int j,int k){
- int ti=i+k<n?x[i+k]:-;
- int tj=j+k<n?x[j+k]:-;
- return ti==tj&&x[i]==x[j];
- }
- void SA_init(){
- int *x=rk,*y=height,r=;
- for(int i=;i<r;i++)w[i]=;
- for(int i=;i<n;i++)w[turn(s[i])]++;
- for(int i=;i<r;i++)w[i]+=w[i-];
- for(int i=n-;i>=;i--)sa[--w[turn(s[i])]]=i;
- r=;x[sa[]]=;
- for(int i=;i<n;i++)
- x[sa[i]]=s[sa[i]]==s[sa[i-]]?r-:r++;
- for(int k=;r<n;k<<=){
- int yn=;
- for(int i=n-k;i<n;i++)y[yn++]=i;
- for(int i=;i<n;i++)
- if(sa[i]>=k)y[yn++]=sa[i]-k;
- for(int i=;i<r;i++)w[i]=;
- for(int i=;i<n;i++)w[x[y[i]]]++;
- for(int i=;i<r;i++)w[i]+=w[i-];
- for(int i=n-;i>=;i--)sa[--w[x[y[i]]]]=y[i];
- swap(x,y);r=;x[sa[]]=;
- for(int i=;i<n;i++)
- x[sa[i]]=pan(y,sa[i],sa[i-],k)?r-:r++;
- }
- }
- void height_init(){
- int i,j,k=;
- for(int i=;i<=n;i++)rk[sa[i]]=i;
- for(int i=;i<n;i++){
- if(k)k--;
- int j=sa[rk[i]-];
- while(s[i+k]==s[j+k])k++;
- height[rk[i]]=k;
- }
- }
- int f[N][],lg[N];
- inline int qpow(int a){return <<a;}
- void st_init(){
- for(int i=;i<=n;i++){
- f[i-][]=height[i];
- lg[i]=lg[i-];
- if((<<lg[i]+)==i)lg[i]++;
- }
- for(int j=;j<=lg[n];j++){
- for(int i=;i<n;i++){
- if(i+qpow(j)->=n)break;
- f[i][j]=min(f[i][j-],f[i+qpow(j-)][j-]);
- }
- }
- }
- int lcp(int i,int j){
- int l=rk[i],r=rk[j];if(l>r)swap(l,r);
- l--;r--;if(r<)return ;l++;
- int len=r-l+,k=lg[len],h=qpow(k);
- return min(f[l][k],f[r-h+][k]);
- }
- int main(){
- int t;scanf("%d",&t);
- while(t--){
- scanf("%s%s",s,p);
- n=strlen(s);int m=strlen(p);
- s[n++]='#';
- for(int i=;i<m;i++)s[n++]=p[i];
- s[n++]=;SA_init();n--;height_init();st_init();
- int ans=;
- for(int i=;i<n-*m;i++){
- int cnt=;
- for(int j=;j<m&&cnt<=;){
- if(s[i+j]!=s[n-m+j])cnt++,j++;
- else j+=lcp(i+j,n-m+j);
- }
- if(cnt<=)ans++;
- }
- printf("%d\n",ans);
- }
- return ;
- }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
洛谷3763:[TJOI2017]DNA——题解的更多相关文章
- [洛谷P3763] [TJOI2017]DNA
洛谷题目链接:[TJOI2017]DNA 题目描述 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其 ...
- 洛谷P3763 [Tjoi2017]DNA 【后缀数组】
题目链接 洛谷P3763 题解 后缀数组裸题 在BZOJ被卡常到哭QAQ #include<algorithm> #include<iostream> #include< ...
- 洛谷P3763 [TJOI2017]DNA(后缀数组 RMQ)
题意 题目链接 Sol 这题打死我也不会想到后缀数组的,应该会全程想AC自动机之类的吧 但知道这题能用后缀数组做之后应该就不是那么难了 首先把\(S\)和\(S0\)拼到一起跑,求出Height数组 ...
- 洛谷P3763 [TJOI2017]DNA(后缀自动机)
传送门 好像用SAM写的很少诶…… 其实我一开始也没想到要用SAM的……主要是没有想到找的时候可以dfs…… 首先建一个SAM,然后跑一遍dfs,枚举一下下一位,如果相同直接继续,否则就花费一次次数来 ...
- 洛谷P2832 行路难 分析+题解代码【玄学最短路】
洛谷P2832 行路难 分析+题解代码[玄学最短路] 题目背景: 小X来到了山区,领略山林之乐.在他乐以忘忧之时,他突然发现,开学迫在眉睫 题目描述: 山区有n座山.山之间有m条羊肠小道,每条连接两座 ...
- 【洛谷P3960】列队题解
[洛谷P3960]列队题解 题目链接 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m ...
- 洛谷P2312 解方程题解
洛谷P2312 解方程题解 题目描述 已知多项式方程: \[a_0+a_1x+a_2x^2+\cdots+a_nx^n=0\] 求这个方程在 \([1,m]\) 内的整数解(\(n\) 和 \(m\) ...
- 洛谷P1577 切绳子题解
洛谷P1577 切绳子题解 题目描述 有N条绳子,它们的长度分别为Li.如果从它们中切割出K条长度相同的 绳子,这K条绳子每条最长能有多长?答案保留到小数点后2位(直接舍掉2为后的小数). 输入输出格 ...
- 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)
洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...
- 洛谷 P1220 关路灯 题解
Description 有 $n$ 盏路灯,每盏路灯有坐标(单位 $m$)和功率(单位 $J$).从第 $c$ 盏路灯开始,可以向左或向右关闭路灯.速度是 $1m/s$.求所有路灯的最少耗电.输入保证 ...
随机推荐
- WPF DataGridRow Event
CM(Caliburn.Micro)框架绑定DataGridRow事件 <DataGrid.ItemContainerStyle> <Style TargetType="D ...
- Ubuntu16.04比较好的一系列软件安装介绍
https://blog.csdn.net/Gerald_Jones/article/details/80784976
- OSG-漫游
本文转至http://www.cnblogs.com/shapherd/archive/2010/08/10/osg.html 作者写的比较好,再次收藏,希望更多的人可以看到这个文章 互联网是是一个相 ...
- Vue动画效果
1.哪些元素/那些组件适合在那些条件下实现动画效果 条件渲染 (使用 v-if) 条件展示 (使用 v-show) 动态组件 组件根节点 简单经典例子:(文字隐藏到显示效果) <div> ...
- HADOOP-输出数据实体类承载
新建一个bean包: 1.实现Writerable 2.有一个空的构造方法 代码实现: import java.io.DataInput; import java.io.DataOutput; imp ...
- ionic 获取input的值
1.参数传递法 例子:获取input框内容 这里有个独特的地方,直接在input处使用 #定义参数的name值,注意在ts中参数的类型 在html页面中 <ion-input type=&quo ...
- 讯飞云 API 语音听写 python3 调用例程
#!/usr/bin/python3 # -*- coding: UTF-8 -*- import requests import time import gzip import urllib imp ...
- parity 注记词
spousal tint untold around rosy daintily unrated sheep choice showpiece chirping gala
- 基于Hadoop2.5.0的集群搭建
http://download.csdn.net/download/yameing/8011891 一. 规划 1. 准备安装包 JDK:http://download.oracle.com/otn ...
- Mybatis ResultMap(2)
SQL 映射XML 文件是所有sql语句放置的地方.需要定义一个workspace,一般定义为对应的接口类的路径.写好SQL语句映射文件后,需要在MyBAtis配置文件mappers标签中引用,例如: ...