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. Appium基础(三)对象抓取

    一.启动Android模拟器 二.打开App应用,这里以计算器为例子 三.打开uiautomatorviewer.bat 这个文件在Android SDK-->Tool目录下 双击uiautom ...

  2. 微信公众号支付(JSAPI)对接备忘

    0 说明 本文里说的微信公众号支付对接指的是对接第三方支付平台的微信公众号支付接口. 非微信支付官方文档里的公众号支付开发者文档那样的对接.不过,毕竟腾讯会把一部分渠道放给银行或有支付牌照的支付机构, ...

  3. 【转载】C# 中的委托和事件(详解:简单易懂的讲解)

    本文转载自http://www.cnblogs.com/SkySoot/archive/2012/04/05/2433639.html C# 中的委托和事件(详解) C# 中的委托和事件 委托和事件在 ...

  4. leetCode-linkedListCycle判断链表是否有环

    题目 Given a linked list, determine if it has a cycle in it. Follow up: Can you solve it without using ...

  5. <<attention is all you need>>速读笔记

    背景 在seq2seq中,一般是有一个encoder 一个decoder ,一般是rnn/cnn 但是rnn 计算缓慢,所以提出了纯用注意力机制来实现编码解码. 模型结构 大部分神经序列转导模型都有一 ...

  6. 原生js实现图片轮播效果

    思路:设置父容器(一定宽度,一定高度,相对定位,子容器超出部分进行隐藏),子容器图片并排(浮动,绝对定位,每次点击进行相应的左或右偏移量) 1.html: <!DOCTYPE html> ...

  7. eclipse maven install没反应解决办法

    .打开eclipse的Window菜单-->java-->Installed JREs .点击用的jdk,edit,在Default VM arguments里面填入-Dmaven.mul ...

  8. NSThread(II)

    非线程安全 //初始化火车票数量.卖票窗口(非线程安全).并开始卖票 - (void)initTicketStatusNotSave { // 1. 设置剩余火车票为 50 self.ticketSu ...

  9. 【Linux学习十】负载均衡带来tomcat的session不一致问题

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 tomcat7 jdk7 session不一致是指web服务器(tom ...

  10. python 内置函数enumerate()

    enumerate() 函数用于将一个可遍历的数据对象(如列表.元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中.在python 3中返回一个生成器,代码如下: a ...