Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem E (Codeforces 828E) - 分块
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!
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 l, r 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.
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.
ATGCATGC
4
2 1 8 ATGC
2 2 6 TTT
1 4 T
2 2 6 TA
8
2
4
GAGTTGTTAA
6
2 3 4 TATGGTG
1 1 T
1 6 G
2 5 9 AGTAATA
1 10 G
2 2 6 TTGT
0
3
1
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) - 分块的更多相关文章
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
随机推荐
- C++调用openssl实现DES加密解密cbc模式 zeropadding填充方式 pkcs5padding填充方式 pkcs7padding填充方式
============================================== des cbc 加密 zeropadding填充方式 ======================= ...
- UVALi 3263 That Nice Euler Circuit(几何)
That Nice Euler Circuit [题目链接]That Nice Euler Circuit [题目类型]几何 &题解: 蓝书P260 要用欧拉定理:V+F=E+2 V是顶点数; ...
- html常用文本标签(转)
内容一<br />内容二 让文本强制换行 内容一内容二 <p>段落一</p><p>段落二</p> 段落标签 段落一 段落二 <b> ...
- 05 enumerate index使用
# enumerate 自动生成一列, 默认0开始,每次自增+1li = ["电脑","鼠标垫","U盘","游艇"]f ...
- hdu5290树形dp
题意 给了n个点的数 每个点有一个w[i]权值,如果你选择了i这个点那么距离i这个点距离为w[i]的点将被除去,最后问 选则尽量少的点把这n个点全部删除 1<=n<=100000, 0&l ...
- 文件、文件夹操作(I)
遍历一个目录下的所有文件 首先我们获取用户文档目录路径 let manager = FileManager.default let urlForDocument = manager.urls(for: ...
- 在lua中从一个字符串中移除空间源码
/* trim.c - based on http://lua-users.org/lists/lua-l/2009-12/msg00951.html from Sean Conner */ #inc ...
- STL容器之map
[1]map容器 map 是关联容器.容器中的每一个元素都是由一个键值和一个数据值组成的. set 是一个集合它以其元素作为键值(同一个键值只能出现一次),且默认以升序排列. list 是一个顺序容器 ...
- 设计模式之State(状态)(转)
State的定义: 不同的状态,不同的行为;或者说,每个状态有着相应的行为. 何时使用? State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If elseif ...
- 【转】Kylin介绍 (很有用)
转:http://blog.csdn.net/yu616568/article/details/48103415 Kylin是ebay开发的一套OLAP系统,与Mondrian不同的是,它是一个MOL ...