zoukankan      html  css  js  c++  java
  • Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) E. DNA Evolution 树状数组

    E. DNA Evolution

    题目连接:

    http://codeforces.com/contest/828/problem/E

    Description

    Everyone knows that DNA strands consist of nucleotides. There are four types of nucleotides: "A", "T", "G", "C". A DNA strand is a sequence of nucleotides. Scientists decided to track evolution of a rare species, which DNA strand was string s initially.

    Evolution of the species is described as a sequence of changes in the DNA. Every change is a change of some nucleotide, for example, the following change can happen in DNA strand "AAGC": the second nucleotide can change to "T" so that the resulting DNA strand is "ATGC".

    Scientists know that some segments of the DNA strand can be affected by some unknown infections. They can represent an infection as a sequence of nucleotides. Scientists are interested if there are any changes caused by some infections. Thus they sometimes want to know the value of impact of some infection to some segment of the DNA. This value is computed as follows:

    Let the infection be represented as a string e, and let scientists be interested in DNA strand segment starting from position l to position r, inclusive.
    Prefix of the string eee... (i.e. the string that consists of infinitely many repeats of string e) is written under the string s from position l to position r, inclusive.
    The value of impact is the number of positions where letter of string s coincided with the letter written under it.
    Being a developer, Innokenty is interested in bioinformatics also, so the scientists asked him for help. Innokenty is busy preparing VK Cup, so he decided to delegate the problem to the competitors. Help the scientists!

    Input

    The first line contains the string s (1 ≤ |s| ≤ 105) that describes the initial DNA strand. It consists only of capital English letters "A", "T", "G" and "C".

    The next line contains single integer q (1 ≤ q ≤ 105) — the number of events.

    After that, q lines follow, each describes one event. Each of the lines has one of two formats:

    1 x c, where x is an integer (1 ≤ x ≤ |s|), and c is a letter "A", "T", "G" or "C", which means that there is a change in the DNA: the nucleotide at position x is now c.
    2 l r e, where l, r are integers (1 ≤ l ≤ r ≤ |s|), and e is a string of letters "A", "T", "G" and "C" (1 ≤ |e| ≤ 10), which means that scientists are interested in the value of impact of infection e to the segment of DNA strand from position l to position r, inclusive.

    Output

    For each scientists' query (second type query) print a single integer in a new line — the value of impact of the infection on the DNA.

    Sample Input

    ATGCATGC
    4
    2 1 8 ATGC
    2 2 6 TTT
    1 4 T
    2 2 6 TA

    Sample Output

    8
    2
    4

    Hint

    题意

    给你一个字符串,然后你有一些操作:

    1.单点更新

    2.查询区间[l,r]中,有多少个字符能和所给的字符串匹配(字符串循环匹配)

    题解:

    树状数组,由于查询的字符串最长10,且字符集直邮4,所以我们直接暴力对T[10][10][4]建树,T[i][j][k]表示这个为长度为i,该字符的位置是j%i,该字符是k,然后去讨论即可。

    代码

    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    
    const int maxn = 1e5+7;
    struct bit{
        int a[maxn];
        int lowbit(int x){
            return x&(-x);
        }
        void update(int x,int v){
            for(int i=x;i<maxn;i+=lowbit(i)){
                a[i]+=v;
            }
        }
        int get(int x){
            int sum=0;
            for(int i=x;i;i-=lowbit(i)){
                sum+=a[i];
            }
            return sum;
        }
        int get(int l,int r){
            return get(r)-get(l-1);
        }
    }T[11][11][4];
    char s[maxn];
    int q;
    int getid(char x){
        if(x=='A')return 0;
        if(x=='T')return 1;
        if(x=='C')return 2;
        if(x=='G')return 3;
    }
    int main(){
        scanf("%s",s+1);
        int len = strlen(s+1);
        for(int j=1;j<=10;j++)
            for(int i=1;i<=len;i++)
                T[j][i%j][getid(s[i])].update(i,1);
        scanf("%d",&q);
        while(q--){
            int op;
            scanf("%d",&op);
            if(op==1){
                int l;
                char t[10];
                scanf("%d%s",&l,t);
                for(int i=1;i<=10;i++){
                    T[i][l%i][getid(t[0])].update(l,1);
                    T[i][l%i][getid(s[l])].update(l,-1);
                }
                s[l]=t[0];
            }else{
                int l,r;
                char t[10];
                scanf("%d%d%s",&l,&r,t);
                int len2=strlen(t);
                int ans = 0;
                for(int i=0;i<len2;i++){
                    ans+=T[len2][(l+i)%len2][getid(t[i])].get(l,r);
                }
                printf("%d
    ",ans);
            }
        }
    }
  • 相关阅读:
    RTLabel 富文本
    代码复用,优化时间
    (转)分享一些免费的接口.无意中查找资料发现
    新手之使用git
    ios 清理缓存
    (转)IOS崩溃 异常处理(NSSetUncaughtExceptionHandler)
    UIApplication的理解
    新提交审核app保留检查更新入口将被拒绝
    (转)免费天气预报接口API以及全国所有地区代码!!
    Cesium快速上手9-Camera和Scene中的其他函数使用
  • 原文地址:https://www.cnblogs.com/qscqesze/p/7190047.html
Copyright © 2011-2022 走看看