codeforces E. DNA Evolution(树状数组)

题目链接:http://codeforces.com/contest/828/problem/E

题解:就是开4个数组举一个例子。

A[mod][res][i]表示到i位置膜mod余数是res的‘A’有多少个。然后以此类推其他碱基。就是单点更新区间求和用树状数组就行具体看一下代码。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int M = 1e5 + 10;
char s[M];
int T[4][11][11][M];
inline void add(int id , int mod , int res , int k , int v) {
    ++k;
    while(k < M) {
        T[id][mod][res][k] += v;
        k += (k & (-k));
    }
}
inline int getsum(int id , int mod , int res , int k) {
    int ret = 0;
    ++k;
    while(k) {
        ret += T[id][mod][res][k];
        k -= (k & (-k));
    }
    return ret;
}
int main() {
    scanf("%s"  ,s);
    int q , n , x , l , r;
    char c[20];
    scanf("%d" , &q);
    memset(T , 0 , sizeof(T));
    int L = strlen(s);
    for(int i = 0 ; i < L ; i++) {
        for(int j = 1 ; j <= 10 ; j++) {
            if(s[i] == 'A') add(0 , j , i % j , i , 1);
            if(s[i] == 'T') add(1 , j , i % j , i , 1);
            if(s[i] == 'G') add(2 , j , i % j , i , 1);
            if(s[i] == 'C') add(3 , j , i % j , i , 1);
        }
    }
    while(q--) {
        scanf("%d" , &n);
        if(n == 1) {
            scanf("%d %s" , &x , c);
            x--;
            for(int i = 1 ; i <= 10 ; i++) {
                if(s[x] == 'A') add(0 , i , x % i , x , -1);
                if(s[x] == 'T') add(1 , i , x % i , x , -1);
                if(s[x] == 'G') add(2 , i , x % i , x , -1);
                if(s[x] == 'C') add(3 , i , x % i , x , -1);
            }
            for(int i = 1 ; i <= 10 ; i++) {
                if(c[0] == 'A') add(0 , i , x % i , x , 1);
                if(c[0] == 'T') add(1 , i , x % i , x , 1);
                if(c[0] == 'G') add(2 , i , x % i , x , 1);
                if(c[0] == 'C') add(3 , i , x % i , x , 1);
            }
            s[x] = c[0];
        }
        else {
            scanf("%d%d%s" , &l , &r , c);
            l--, r--;
            int len = strlen(c);
            int ans = 0;
            for(int i = 0 ; i < len ; i++) {
                if(c[i] == 'A') ans += (getsum(0 , len , (i + l) % len , r) - (l == 0 ? 0 : getsum(0 , len , (i + l) % len , l - 1)));
                if(c[i] == 'T') ans += (getsum(1 , len , (i + l) % len , r) - (l == 0 ? 0 : getsum(1 , len , (i + l) % len , l - 1)));
                if(c[i] == 'G') ans += (getsum(2 , len , (i + l) % len , r) - (l == 0 ? 0 : getsum(2 , len , (i + l) % len , l - 1)));
                if(c[i] == 'C') ans += (getsum(3 , len , (i + l) % len , r) - (l == 0 ? 0 : getsum(3 , len , (i + l) % len , l - 1)));
            }
            printf("%d
" , ans);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/TnT2333333/p/7159400.html