DNA Evolution 【CodeForces - 828E(827C)】【树状数组】

题目链接


  很难的一道题吧,算是挺难了,就是想到挺复杂,作为我这么个Ju蒻来说。

  题目给你一串字符串,是初始的字符串,然后告诉你一系列操作,问你:

(一)、改变点Xi上的字符;

(二)、查询【l,r】区间上的对应与新给的字符串匹配的个数是几个?例如“ACGTCGA”我们待查的是这个完整区间上的“AG”,那么“AG”会变成“AGAGAGA”与上述对应的点的个数就是3,第一位与最后两位。


  思路:我们发现一点,就是待查询的区间长度很短,不超过10,那么我们是不是可以从中挖掘出什么来,既然最大长度为10,我们不如先做些预处理,知道原字符串的样子,我们通过其来初始化一下,就是看作每个分块。

  怎么看作小分块?我们从1~10的大小拆分按序全体字符串,这个的目的是在于区分长度,然后,去看对应字符串字符又是不同的,怎么处理?可以再开个空间,反正就是4个字符,多开4倍还是够的,接下来的问题就是一一对应,怎么样做到一一对应?我们既然已经对字符串的待判长度做了预处理,不妨在想个办法判断出其在拆分出的字符串中应当存在的位子,我们从0~len-1来排位子就是只需要将字符所在位子去%此时的对应长度,就可以得到它应当存在的区间。

  那么树状数组的开法就应当是这样的:C[在长度为len的条件下排在第几个][预处理长度len][元素符号][存在原数组中的第pos位]。那么,我们就可以建立树状数组了。

  细节上别忘了,每次树状数组更新后记得也要改变原字符串中对应位子的元素符号。


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 100005;
//const ull Hash1=1e9+7, Hash2=1e9+9;
//const char fu[5] = { ' ', 'A' , 'T', 'G', 'C' };
const int re_fu[26] = { 1, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0 };     //fu[]-'A',在其中代表Z(对应符号所在的数位)
char s[maxN], ques[15];
int N, Q, flag, l, r, len;
int C[11][11][5][maxN];
void update(int x, int y, int z, int pos, int val)  //x为数长、y为我们将其放在第几个、z是对应的数位置,pos是我们存入的位子,val是放一个(或者删除一个)
{
    while(pos<maxN)
    {
        C[x][y][z][pos] += val;
        pos += lowbit(pos);
    }
}
int query(int x, int y, int z, int pos)     //x为将其视为第几个,y是查询数的长度,z是待查询的数,pos是对应前缀
{
    int res=0;
    while(pos)
    {
        res += C[x][y][z][pos];
        pos -= lowbit(pos);
    }
    return res;
}
int main()
{
    while(scanf("%s", s+1)!=EOF)
    {
        memset(C, 0, sizeof(C));
        N = (int)strlen(s+1);
        for(int i=1; i<=N; i++)
        {
            for(int j=1; j<=10; j++)
            {
                update(i%j, j, re_fu[s[i]-'A'], i, 1);
            }
        }
        scanf("%d", &Q);
        while(Q--)
        {
            scanf("%d", &flag);
            if(flag == 1)
            {
                scanf("%d", &l);
                scanf("%s", ques);
                for(int i=1; i<=10; i++)
                {
                    update(l%i, i, re_fu[s[l]-'A'], l, -1);
                    update(l%i, i, re_fu[ques[0]-'A'], l, 1);
                }
                s[l] = ques[0];
            }
            else
            {
                int ans = 0;
                scanf("%d%d", &l, &r);
                scanf("%s", ques);
                len = (int)strlen(ques);
                for(int i=0; i<len; i++)
                {
                    ans += query((l+i)%len, len, re_fu[ques[i]-'A'], r) - query( (l+i)%len, len, re_fu[ques[i]-'A'], l-1);
                }
                printf("%d\n", ans);
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41730082/article/details/84070314
DNA
今日推荐