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
ATGCATGC
4
2 1 8 ATGC
2 2 6 TTT
1 4 T
2 2 6 TA
output
8
2
4
input
GAGTTGTTAA
6
2 3 4 TATGGTG
1 1 T
1 6 G
2 5 9 AGTAATA
1 10 G
2 2 6 TTGT
output
0
3
1
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.


  我告诉我同学我用分块把这道题A掉了,我同学喷我为毛不去打比赛,我表示这场比赛A,B题好坑啊。。

  不多扯废话了。

  题目大意 给定一个字符串和一些操作。操作是修改字符串某个位置的字符,查询是给定一个比较短的字符串从这个字符串的a位置开始,一直到b位置,循环这个较短的字符串进行逐字节比较,输出匹配的字符数。

  不难想到用各种线段树,树状数组,然而为了简单粗暴,我选择了分块(显然树状数组做起来更简单)。

  根据常用套路,很容易得到每个块要记录下标模1到模10的余数为r,字符为c的出现次数。

  初始化块的时候暴力3重for去统计。修改时for模数,然后按意思修改一下就好了(注意字符串也要改)。

  查询时,先判断起始是否在同一块中,如果在,直接暴力for去算答案。否则就暴力for块两端的部分,中间暴力枚举块存储的数据,根据模查询字符串长度下的模数去统计(我也不好说清楚,是在不懂可以看代码,如果还不懂,就在评论区问一下吧)。

  总时间复杂度

Code

 /**
* Codeforces
* Problem#828E
* Accepted
* Time:1107ms
* Memory:4104k
*/
#include <iostream>
#include <cstdio>
#include <ctime>
#include <cmath>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <stack>
#ifndef WIN32
#define Auto "%lld"
#else
#define Auto "%I64d"
#endif
using namespace std;
typedef bool boolean;
const signed int inf = (signed)((1u << ) - );
const signed long long llf = (signed long long)((1ull << ) - );
const double eps = 1e-;
const int binary_limit = ;
#define smin(a, b) a = min(a, b)
#define smax(a, b) a = max(a, b)
#define max3(a, b, c) max(a, max(b, c))
#define min3(a, b, c) min(a, min(b, c))
template<typename T>
inline boolean readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-' && x != -);
if(x == -) {
ungetc(x, stdin);
return false;
}
if(x == '-'){
x = getchar();
aFlag = -;
}
for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
ungetc(x, stdin);
u *= aFlag;
return true;
} int cti(char x) {
if(x == 'A') return ;
if(x == 'C') return ;
if(x == 'G') return ;
return ;
} typedef class Chunk {
public:
int id;
int counter[][][]; // moder, rest, character Chunk() { };
Chunk(int id):id(id) {
memset(counter, , sizeof(counter));
}
}Chunk; int n, m;
int cs, cc;
char s[];
vector<Chunk> lis; inline void init() {
gets(s);
readInteger(n);
m = strlen(s);
cs = (int)sqrt(m + 0.5);
} inline int disposeWithBeginning(int a, char* buf, int len) {
int sid = a / cs, ret = ;
for(int i = a; i < (sid + ) * cs; i++) {
if(s[i] == buf[(i - a) % len])
ret++;
}
return ret;
} inline int disposeWithEnding(int a, int b, char* buf, int len) {
int eid = b / cs, ret = ;
for(int i = eid * cs; i <= b; i++) {
if(s[i] == buf[(i - a) % len])
ret++;
}
return ret;
} inline void init_chunks() {
for(cc = ; cc * cs <= m; cc++) {
Chunk b(cc);
for(int mod = ; mod <= ; mod++) {
for(int rest = ; rest < mod; rest++) {
int start_pos = cc * cs - (cc * cs) % mod + rest;
if(start_pos < cc * cs) start_pos += mod;
for(int i = start_pos; i < (cc + ) * cs; i += mod)
b.counter[mod][rest][cti(s[i])]++;
}
}
lis.push_back(b);
}
} inline void solve() {
int opt, a, b, len, res;
char buf[];
while(n--) {
readInteger(opt);
readInteger(a);
a--;
if(opt == ) {
scanf("%s", buf);
int bid = a / cs;
char bchar = s[a];
for(int mod = ; mod <= ; mod++) {
b = a % mod;
lis[bid].counter[mod][b][cti(buf[])]++, lis[bid].counter[mod][b][cti(bchar)]--;
}
s[a] = buf[];
} else {
res = ;
readInteger(b);
b--;
scanf("%s", buf);
len = strlen(buf);
int sid = a / cs, eid = b / cs;
if(sid == eid) {
for(int i = a; i <= b; i++) {
if(s[i] == buf[(i - a) % len])
res++;
}
} else {
for(int i = sid + ; i < eid; i++) {
int base = (i * cs - a) % len;
int rbase = (i * cs) % len;
for(int j = ; j < len; j++) {
res += lis[i].counter[len][(rbase + j) % len][cti(buf[(base + j) % len])];
}
}
res += disposeWithBeginning(a, buf, len);
res += disposeWithEnding(a, b, buf, len);
}
printf("%d\n", res);
}
}
} int main() {
init();
init_chunks();
solve();
return ;
}

Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem E (Codeforces 828E) - 分块的更多相关文章

  1. Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem D (Codeforces 828D) - 贪心

    Arkady needs your help again! This time he decided to build his own high-speed Internet exchange poi ...

  2. Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem C (Codeforces 828C) - 链表 - 并查集

    Ivan had string s consisting of small English letters. However, his friend Julia decided to make fun ...

  3. 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 i ...

  4. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem C (Codeforces 831C) - 暴力 - 二分法

    Polycarp watched TV-show where k jury members one by one rated a participant by adding him a certain ...

  5. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem F (Codeforces 831F) - 数论 - 暴力

    题目传送门 传送门I 传送门II 传送门III 题目大意 求一个满足$d\sum_{i = 1}^{n} \left \lceil \frac{a_i}{d} \right \rceil - \sum ...

  6. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem D (Codeforces 831D) - 贪心 - 二分答案 - 动态规划

    There are n people and k keys on a straight line. Every person wants to get to the office which is l ...

  7. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem E (Codeforces 831E) - 线段树 - 树状数组

    Vasily has a deck of cards consisting of n cards. There is an integer on each of the cards, this int ...

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

    Codeforces Round #423 (Div. 1, rated, based on VK Cup Finals) A.String Reconstruction B. High Load C ...

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

    E. DNA Evolution 题目连接: http://codeforces.com/contest/828/problem/E Description Everyone knows that D ...

随机推荐

  1. cocos2dx JS 层(Layer)的生命周期

    场景的生命周期: 一般情况下一个场景只需要一个层,需要创建自己的层类.一些主要的游戏逻辑代码都是写在层中的,场景的生命周期是通过层的生命周期反映出来的,通过重写层的生命周期函数,可以处理场景不同声明周 ...

  2. RMAN备份策略与异机恢复一例(续篇)

    本文是<RMAN备份策略与异机恢复一例>的续篇,继续实验验证,最终实现两个需求: 1.异机恢复临时测试的小库 2.传输归档时,实现增量传输 1.异机恢复临时测试的小库 之前异机恢复的需求已 ...

  3. Adobe Flash Builder 调试器无法连接,无法进行调试,构建停止在57%

    参考:https://blog.csdn.net/wuboyaogun1/article/details/9105373 谷歌浏览器下载Flash debugger :Download the Win ...

  4. .NET 黑魔法 - asp.net core 配置文件的"对象存储"

    来,全都是干货. 我们都知道在Framework版本的mvc项目中,配置数据是通过web.config里的appSettings节点配置,我们不得不写一些读取配置文件字符串的类,比如保存在静态的变量中 ...

  5. 《大话设计模式》c++实现 原型模式

    意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 主要解决:在运行期建立和删除原型. 何时使用: 1.当一个系统应该独立于它的产品创建,构成和表示时. 2.当要实例化的类是在运行 ...

  6. Rpgmakermv(30) GameQuest任务插件

    插件简介: 很牛X的任务插件(个人目前用过中的) 插件用法说明 Report any bugs, editor or plugin related here: http://forums.rpgmak ...

  7. STM32 一个定时器产生4路 独立调频率,占中比可调,脉冲个数可以统计。

    实现这个功能,基本原理是利用STM32 的输出比较功能. 1.其它设置就是普通定时器的设置这里开启,四个输出比较中断,和一个更新中断, 更新中断这里不需要开也可以达到目的,我这里开启是做其它的用处的. ...

  8. 初探AngularJs框架(三)

    一.实现todoList的demo 功能很简单,提供一个文本框,用户输入回车后添加新条目.每个条目可以在待处理和处理中两个区域间切换,每个条目都可以被删除,大致的界面如下图所示: 二.处理逻辑 首先将 ...

  9. Codeforce 814A - An abandoned sentiment from past (贪心)

    A few years ago, Hitagi encountered a giant crab, who stole the whole of her body weight. Ever since ...

  10. [转载]C#中Invoke的用法()

    invoke和begininvoke 区别 一直对invoke和begininvoke的使用和概念比较混乱,这两天看了些资料,对这两个的用法和原理有了些新的认识和理解. 首先说下,invoke和beg ...