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 ...
随机推荐
- 使用sqlite3解决IDEA中SVN更新提示cleanup却无法cleanup的问题
用idea开发项目,更新svn有时莫名其妙的出现 Error:Error performing cleanup for 'D:\SourceProject\XXXX': svn: E155004: T ...
- c++基础:之泛型与标准模板库
- 学习笔记: ES7(ES2016)新功能
ES7添加了两个新功能 : 1. Array.prototype.includes() 2. 指数运算符 1 .Array.prototype,includes() 判断指定的元素是否存在于数组中, ...
- 记学习hadoop时无法启动namenode的问题
1. 按照apache的文档,学习搭建hadoop. 2. 当把机器重启之后发现无法启动 namenode. 3. 查看日志发现是一些文件找不到,这些文件的位置是在/tmp目录下的,而/tmp 目录下 ...
- Unity shader学习之屏幕后期处理效果之高斯模糊
高斯模糊,见 百度百科. 也使用卷积来实现,每个卷积元素的公式为: 其中б是标准方差,一般取值为1. x和y分别对应当前位置到卷积中心的整数距离. 由于需要对高斯核中的权重进行归一化,即使所有权重相加 ...
- Unity shader学习之屏幕后期处理效果之均值模糊
均值模糊,也使用卷积来实现,之不过卷积中每个值均相等,且相加等于1. 代码如下, 子类: using UnityEngine; public class MeanBlurRenderer : Post ...
- Unity shader学习之半兰伯特光照模型
半兰伯特光照模型,为Valve公司在开发游戏<半条命>时提出的一种技术,用于解决漫反射光无法到达区域无任凭明暗变化,丢失模型细节表现的问题. 其公式如下: Cdiffuse = Cligh ...
- rpgmakermv(8) XY_TitleMenu插件
插件作用:设置标题 /*: * @plugindesc v1.00 Display Multiple Menu in Title Screen. * @author XueYu Plugins * * ...
- 【Elasticsearch学习之三】Elasticsearch 搜索引擎案例
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 elasticsearch-2.2.0 第一步:获取数据主流 ...
- 配置tomcat的https域名
配置tomcat的https域名: <Connector port=" protocol="org.apache.coyote.http11.Http11NioProtoco ...