zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Swift
    UIWindow 详解及使用场景
    点击状态栏回到顶部的功能失效的解决办法
    iOS
    从经典问题来看 Copy 方法
    从汇编层面深度剖析C++虚函数
    数值的整数次方
    求整数二进制中1的个数
    C++中的位运算总结
    嵌入在C++程序中的extern "C"
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/7159400.html
Copyright © 2011-2022 走看看