zoukankan      html  css  js  c++  java
  • 核苷酸(evolution)

    核苷酸(evolution)

    题目描述

     

    生物课是帕特里克最讨厌的课程,没有之一。

    相比做一些无聊而又无趣的遗传题,他更喜欢其他所有的科目。

    包括英语。

    但是今天不同。他被一个关于RNA感染DNA的题目所吸引了。

    我希望能够实现这样的一个功能。

    DNA中包含四种核苷酸,上面具有不同的含氮碱基,分别是:腺嘌呤(A)、胸腺嘧啶(T)、鸟嘌呤(G)、胞嘧啶(C)。我们可以用形如ATTGCA...的字符串来代表一条脱氧核苷酸序列。

    我们需要追踪一段高变异生物的核苷酸序列。在这种生物中,其DNA序列很容易发生替换,即将某一位的核苷酸替换为其他核苷酸。

    我们有一段感染串,这一条DNA单链极有可能替换原来DNA链中的核苷酸。已知这条单链会作用于[l,r][l,r]中的位置。这条单链会不重叠复制成一条长链,然后顺序感染[l,r][l,r]中的核苷酸。如果两个位置间的核苷酸不同,那么DNA链上的核苷酸就会被替换。

    现在研究人员想知道,对于感染串TT,在[l,r][l,r]上有多少个位置不会受到感染。

     

    输入

     

     

    第一行一串字符串,初始DNA链SS。SS仅由A,T,G,C四个大写字母组成。

    接下来一行带有一个整数QQ。接下来QQ行每行一个询问,格式如下:

    1 x C,表示第xx位置上的核苷酸被替换成字符CC。

    2 l r T,表示有可能有一个感染串TT,在[l,r][l,r]间作用。

    注意,每次感染串并不会对原串做出任何修改。

     

     

     

    输出

     

    对于每个查询22,输出不会受感染的核苷酸位置数量。

     

    样例输入

    【样例1输入】
    ATGCATGC
    4
    2 1 8 ATGC
    2 2 6 TTT
    1 4 T
    2 2 6 TA
    【样例2输入】
    GAGTTGTTAA
    6
    2 3 4 TATGGTG
    1 1 T
    1 6 G
    2 5 9 AGTAATA
    1 10 G
    2 2 6 TTGT

    样例输出

    【样例1输出】
    8
    2
    4
    【样例2输出】
    0
    3
    1

    提示

     

    你可以将感染串理解成一个循环节为|T||T|的无限长字符串。

    请结合两个样例理解其意义。

     

    对于30%的数据,1≤|S|,Q≤1031≤|S|,Q≤103。

    对于另外10%的数据,没有修改操作。

    对于另外10%的数据,基因串仅由A,T两字符构成。

    对于所有数据,满足:1≤|S|,Q≤105,1≤|T|≤101≤|S|,Q≤105,1≤|T|≤10,询问中x,l,r≤|S|x,l,r≤|S|。所有字符与字符串均只包含A,T,G,C。

    另,最伟大的创造是光合作用。

     

     

    来源

    lhy

     

    solution

    令a[p][m][r][x]表示S串中前x个位置

    有多少个字母p (ATGC)的位置

    模m

    余r

    对于每一位s[x]

    a[s[x]][mod][i%mod][x]++;

    前缀和维护即可

     

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int n,Q,m,a[4][11][11][100005],op,pl,l,r;
    char s[100005],ch[15],dy[200],tt;
    void jia(int c,int p,int r,int x,int v){
    	for(;x<=n;x+=(x&-x))a[c][p][r][x]+=v;
    }
    int cha(int c,int p,int r,int x){
    	int vv=0;
    	for(;x>0;x-=(x&-x))vv+=a[c][p][r][x];
    	return vv;
    }
    int main()
    {
    	dy['A']=0;dy['T']=1;dy['G']=2;dy['C']=3;
    	scanf("%s",s+1);
    	n=strlen(s+1);
    	for(int i=1;i<=n;i++){
    		for(int mod=1;mod<=10;mod++){
    			jia(dy[s[i]],mod,i%mod,i,1);
    		}
    	}
    	cin>>Q;
    	while(Q--){
    		scanf("%d",&op);
    		if(op==1){
    			scanf("%d %c",&pl,&tt);
    			for(int mod=1;mod<=10;mod++){
    				jia(dy[s[pl]],mod,pl%mod,pl,-1);
    				jia(dy[tt],mod,pl%mod,pl,1);
    			}
    			s[pl]=tt;
    		}
    		else {
    			scanf("%d%d%s",&l,&r,ch);
    			m=strlen(ch);
    			int sum=0;
    			for(int i=0;i<m;i++){
    				int s1=cha(dy[ch[i]],m,(i+l)%m,l-1);
    				int s2=cha(dy[ch[i]],m,(i+l)%m,r);
    				sum+=s2-s1;
    			}
    			printf("%d
    ",sum);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    OOP & Pointer: Segment Tree
    ICPC_2020 上海站
    Notes: Kirchhoff's Matrix 基尔霍夫矩阵
    CS61A Homework: Church Numerals
    题解:[COCI2011-2012#5] BLOKOVI
    题解:SDOI2017 新生舞会
    题解:POI2012 Salaries
    题解:洛谷P1357 花园
    题解:CF593D Happy Tree Party
    题解 P2320 【[HNOI2006]鬼谷子的钱袋】
  • 原文地址:https://www.cnblogs.com/liankewei/p/10358865.html
Copyright © 2011-2022 走看看