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\n", ans);
        }
    }
    return 0;
}
/*
ATGCATGC
4
2 1 8 ATGC
2 2 6 TTT
1 4 T
2 2 6 TA
*/

 

posted @ 2018-08-24 14:51  KirinSB  阅读(182)  评论(0编辑  收藏  举报