Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) E. DNA Evolution 树状数组

E. DNA Evolution

time limit per test

2 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

Everyone knows that DNA strands consist of nucleotides. There are four types of nucleotides: "A", "T", "G", "C". A DNA strand is a sequence of nucleotides. Scientists decided to track evolution of a rare species, which DNA strand was string s initially.

Evolution of the species is described as a sequence of changes in the DNA. Every change is a change of some nucleotide, for example, the following change can happen in DNA strand "AAGC": the second nucleotide can change to "T" so that the resulting DNA strand is "ATGC".

Scientists know that some segments of the DNA strand can be affected by some unknown infections. They can represent an infection as a sequence of nucleotides. Scientists are interested if there are any changes caused by some infections. Thus they sometimes want to know the value of impact of some infection to some segment of the DNA. This value is computed as follows:

  • Let the infection be represented as a string e, and let scientists be interested in DNA strand segment starting from position l to position r, inclusive.
  • Prefix of the string eee... (i.e. the string that consists of infinitely many repeats of string e) is written under the string s from position lto position r, inclusive.
  • The value of impact is the number of positions where letter of string s coincided with the letter written under it.

Being a developer, Innokenty is interested in bioinformatics also, so the scientists asked him for help. Innokenty is busy preparing VK Cup, so he decided to delegate the problem to the competitors. Help the scientists!

Input

The first line contains the string s (1 ≤ |s| ≤ 105) that describes the initial DNA strand. It consists only of capital English letters "A", "T", "G" and "C".

The next line contains single integer q (1 ≤ q ≤ 105) — the number of events.

After that, q lines follow, each describes one event. Each of the lines has one of two formats:

  • 1 x c, where x is an integer (1 ≤ x ≤ |s|), and c is a letter "A", "T", "G" or "C", which means that there is a change in the DNA: the nucleotide at position x is now c.
  • 2 l r e, where lr are integers (1 ≤ l ≤ r ≤ |s|), and e is a string of letters "A", "T", "G" and "C" (1 ≤ |e| ≤ 10), which means that scientists are interested in the value of impact of infection e to the segment of DNA strand from position l to position r, inclusive.

Output

For each scientists‘ query (second type query) print a single integer in a new line — the value of impact of the infection on the DNA.

Examples

input

ATGCATGC42 1 8 ATGC2 2 6 TTT1 4 T2 2 6 TA

output

824

input

GAGTTGTTAA62 3 4 TATGGTG1 1 T1 6 G2 5 9 AGTAATA1 10 G2 2 6 TTGT

output

031

Note

Consider the first example. In the first query of second type all characters coincide, so the answer is 8. In the second query we compare string "TTTTT..." and the substring "TGCAT". There are two matches. In the third query, after the DNA change, we compare string "TATAT..."‘ with substring "TGTAT". There are 4 matches.

题意:给你一个字符串只有ATCG四个字符

   q个操作,

   1操作,将x位置修改成字符c

   2操作,求区间[l,r]去匹配e,e一直循环,求所有匹配的数目;

思路:数组数组,注意e的长度为[1,10];

   //表示 长度为i 以j为起点的循环节为i 字符为c的位置标记,详见代码;

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
#include<vector>
#include<list>
#include<set>
#include<map>
using namespace std;
#define LL long long
#define pi (4*atan(1.0))
#define eps 1e-14
#define bug(x)  cout<<"bug"<<x<<endl;
const int N=1e5+10,M=2e6+10,inf=1e9+10;
const LL INF=1e18+10,mod=1e9+7;

struct AYT
{
    int tree[N];
    int lowbit(int x)
    {
        return x&-x;
    }
    void update(int x,int c)
    {
        while(x<N)
        {
            tree[x]+=c;
            x+=lowbit(x);
        }
    }
    int query(int x)
    {
        int ans=0;
        while(x)
        {
            ans+=tree[x];
            x-=lowbit(x);
        }
        return ans;
    }
};
AYT tree[11][11][4];//表示 长度为i 以j为起点的循环节为i 字符为c的位置标记
int gc(char a)
{
    if(a==‘A‘)return 0;
    if(a==‘T‘)return 1;
    if(a==‘C‘)return 2;
    return 3;
}
char a[N],ch[10]="ATCG";
int main()
{
    scanf("%s",a+1);
    int n=strlen(a+1);
    for(int i=1; i<=10; i++)
    {
        for(int j=1; j<=i; j++)
        {
            for(int k=0; k<4; k++)
            {
                for(int l=j; l<=n; l+=i)
                    if(ch[k]==a[l])
                        tree[i][j][k].update(l,1);
            }
        }
    }
    int q;
    scanf("%d",&q);
    while(q--)
    {
        int t;
        scanf("%d",&t);
        if(t==1)
        {
            int x;
            char f[2];
            scanf("%d%s",&x,f);
            if(a[x]==f[0])continue;
            for(int i=1; i<=10; i++)
            {
                for(int j=1; j<=i; j++)
                {
                    if(x%i==j%i)
                    for(int k=0; k<4; k++)
                    {
                        if(a[x]==ch[k])
                            tree[i][j][k].update(x,-1);
                        if(f[0]==ch[k])
                            tree[i][j][k].update(x,1);
                    }
                }
            }
            a[x]=f[0];
        }
        else
        {
            int l,r,ans=0;
            char f[12];
            scanf("%d%d%s",&l,&r,f+1);
            int len=strlen(f+1);
            for(int i=1; i<=len; i++)
            {
                int x=gc(f[i]);
                int s=(l+i-1)%len?(l+i-1)%len:len;
                ans+=tree[len][s][x].query(r)-tree[len][s][x].query(l-1);
            }
            printf("%d\n",ans);
        }
    }
    return 0;
}
时间: 2024-08-08 13:57:10

Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) E. DNA Evolution 树状数组的相关文章

Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) E DNA Evolution

DNA Evolution 题目让我们联想到树状数组或者线段树,但是如果像普通那样子统计一段的和,空间会爆炸. 所以我们想怎样可以表示一段区间的字符串. 学习一发大佬的解法. 开一个C[10][10][4][n],就可以啦,第二维表示e的长度,第一维表示i%e的长度,第三维表示颜色,第四维求和了. 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1e5+5; 4 char s[maxn]; 5 map&l

Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Cards Sorting(树状数组)

Cards Sorting time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Vasily has a deck of cards consisting of n cards. There is an integer on each of the cards, this integer is between 1 and 100?0

Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem A - B

Pronlem A In a small restaurant there are a tables for one person and b tables for two persons. It it known that n groups of people come today, each consisting of one or two people. If a group consist of one person, it is seated at a vacant one-seate

Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals)D. High Load

题意:出n个点,其中k个叶子节点,问构造出的树最远的两个点最近是多少 思路:以一个点为中心,然后m个伸出,一层层扩散,(n-1)%m==k,如果k==0,即可以平分,长度就是2*(n-1)/m,如果取模为k==1,说明多出一个,+1,其他的话,就是最后一层补k个,但是最长的还是+2 1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main(){ 5 int n,m; 6 cin>>n>>m; 7 int

Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) B. Black Square

题意:问是否可以形成一个全黑正方形 思路:可以找出正方形的边,然后判断下这个矩阵是否容得下,n,m都比边短,比赛的时候写麻烦了,还去找了这个正方形究竟在哪个位置,这样的话得考虑很多情况,不如就边*边-黑子的总数 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=2e5+10; 5 char a[102][102]; 6 int main(){ 7 int n,m; 8 s

Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) C. String Reconstruction

题意:给出各个字符串出现的起始位置,问整个的字符串是什么,(字典序最小) 思路:开始写的是用set+优先队列存取每个位置出现的最长字符串,然后遍历,爆内存...爆...内...存...我们可以用并查集,已经确认的位置他们并在一起,指向后面第一个没有被确认的(看代码理解吧) 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=2e6+10; 4 5 int n,fa[N]; 6 char s[N],b[N]; 7 8 in

Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals)爆零记

昨晚一个瓜皮说今晚有cf,听说是晚间场,我瞅了一眼,娃,VK Cup,上分的好机会,看着比赛时间就有点心酸了,0:35,当时一直在纠结要不要打的问题,当时想着应该不难吧,要不打一下吧,要不还是看看题先,如果容易就打,难的话就不打了好的吧!于是就这样愉快的决定了.......cf日常延时10分钟,0:45,要不要去睡觉啊,干脆先睡一觉好了,然后又是忍不住诱惑在等待开始! 比赛一开始,瞅了一眼A,这不是一道水题嘛,直接敲啊,然后1分钟就搞定了,交了就过了,B题直接求边界点就好了,扫了一遍就过了,C题

Codeforces Round #423 (Div. 1, rated, based on VK Cup Finals)

A.String Reconstruction B. High Load C. DNA Evolution 题意:给定一个只包含A,T,C,G的字符串S,有如下两种操作 1)修改一个点的字母. 2)给定一个字符串e ($\left | e \right |\leq 10$),生成一个由e重复组成的新串,eee...,问$S_{l..r}$中有几个字母跟这个新的字符串一一对应. SOL:对于每个字母,用BIT[x][y][L]表示$S_{1..L}$中,所有$\equiv x\left (mod

Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals)

D题fst了,生无可恋.第二场rated的CF,打得精神恍惚 A. Unimodal Array 题意:判断数列是否是单峰的. 像题意那样分为三个阶段随便判一判就好了 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> using namespace std; int n,x[105],part=1; bool f=1; int main() { scanf(&quo