• CodeForces 828E DNA Evolution(树状数组)题解


    题意:给你一个串k,进行两个操作:

    “1 a b”:把a位置的字母换成b

    “2 l r s”:求l到r有多少个字母和s匹配,匹配的条件是这样:从l开始无限循环s形成一个串ss,然后匹配ss和指定区间的匹配个数,如图。

    无标题1.png

    思路:用树状数组预处理。因为模板串是不断重复循环的,所以我们可以一个位置一个位置求。对于长len的模板串来说,如果位置i,j满足 i%len == j%len,那么i和j匹配时对模板串来说是一样的(匹配同一个字符)。所以我们定义node[字母][模板串长度][相对位置][位置]来遍历某个位置字符在所有可能的相对位置的情况。

    参考:Codeforces - 828E DNA Evolution —— 很多棵树状数组

    代码:

    #include<stack>
    #include<vector>
    #include<queue>
    #include<set>
    #include<cstring>
    #include<string>
    #include<sstream>
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #define ll long long
    #define ull unsigned long long
    using namespace std;
    const int maxn = 100000 + 10;
    const int seed = 131;
    const int MOD = 100013;
    const int INF = 0x3f3f3f3f;
    char s[maxn];
    int h[255];
    int node[5][11][11][maxn];
    int lowbit(int x){
        return x&(-x);
    }
    void update(int letter, int x, int val){
        for(int i = x; i < maxn; i += lowbit(i)){
            for(int len = 1; len <= 10; len++){
                node[letter][len][x % len][i] += val;
            }
        }
    }
    int sum(int letter, int x, int len, int pos){
        int ans = 0;
        for(int i = x; i > 0; i -= lowbit(i)){
            ans += node[letter][len][pos][i];
        }
        return ans;
    }
    int query(int l, int r, int len, int letter, int pos){
        return sum(letter, r, len, pos) - sum(letter, l - 1, len, pos);
    }
    int main(){
        memset(node, 0 , sizeof(node));
        h['A'] = 1, h['G'] = 2, h['C'] = 3, h['T'] = 4;
        scanf("%s", s + 1);
        int len = strlen(s + 1);
        for(int i = 1; i <= len; i++){
            update(h[s[i]], i, 1);
        }
        int q;
        scanf("%d", &q);
        while(q--){
            int o,u,v;
            char ss[12];
            scanf("%d", &o);
            if(o == 1){
                scanf("%d%s", &u, ss);
                update(h[s[u]], u, -1);
                update(h[ss[0]], u, 1);
                s[u] = ss[0];
            }
            else{
                scanf("%d%d%s", &u, &v, ss);
                len = strlen(ss);
                int ans = 0;
                for(int i = 0; i < len; i++){
                    ans += query(u, v, len, h[ss[i]], (u + i) % len);
                }
                printf("%d
    ", ans);
            }
        }
        return 0;
    }
    /*
    ATGCATGC
    4
    2 1 8 ATGC
    2 2 6 TTT
    1 4 T
    2 2 6 TA
    */
  • 相关阅读:
    Mybatis原理
    周六上课随记
    第一次外包面试
    复习所想
    如何解决高并发下的超卖问题
    Tomcat架构解析
    即将逝去的25岁
    go 刷算法第一题——反转字符串
    JavaScript杂货
    jdk17新特性
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9529853.html
Copyright © 2020-2023  润新知