Codeforces - 828E DNA Evolution —— 很多棵树状数组
题目链接:http://codeforces.com/contest/828/problem/E
2 seconds
512 megabytes
standard input
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 l to 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.
题意:
给出一个DNA序列(n<=1e5),有两种操作:
1. 1 x c 表示将x位置的碱基换成c
2. 2 l r e 表示一个询问:e字符串(|e|<=10)在[l,r]区间内循环出现,问有多少个位置的字符相同?
题解:
1.看到这题的直觉就是要构建一种数据结构,线段树或树状数组之类的。但是直接把整个DNA序列放到一棵树状数组上,是无法操作的。
2.那么就尝试着把DNA序列放到四棵树状数组中,每一颗代表着一种碱基。但对于匹配这个问题,还是只能用逐个位置匹配的枚举操作。
3.再回看题目,发现|e|最大只有10,那么突破点很可能在此。又因为在区间[l,r]匹配时,e循环出现。循环出现,即加入i%|e| = j%|e|,那么i和j这两个位置上的字符是相同的(对于e来说)。
4.根据第三点,可以开10*10*4棵树状数组,把DNA序列分解然后放入其中。bit[len][r_pos][ch]表示:在e的长度为len的情况下,DNA序列第i个位置的相对位置为r_pos = i%len,且这个位置的碱基为ch,则往这棵树状数组的i位置加上1。在统计时,只需枚举e的每一个字符,然后找到其在DNA序列上相对于e的相对位置,从而确定是哪一棵树状数组,再直接统计[l,r]区间上的个数即可。
5.这样设计树状数组,主要是利用到e在区间内重复出现,即如果i%|e| = j%|e|的特性,那么i和j就可以一起统计了。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <sstream>
#include <algorithm>
using namespace std;
typedef long long LL;
const double eps = 1e-;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = 1e5+; struct BIT
{
int c[MAXN];
int lowbit(int x)
{
return x&(-x);
}
void add(int x, int d)
{
for(; x<MAXN; x += lowbit(x))
c[x] += d;
}
int query(int x)
{
int ret = ;
for(; x; x -= lowbit(x))
ret += c[x];
return ret;
}
int getsum(int l, int r)
{
return query(r)-query(l-);
}
}bit[][][]; int M[];
char s[MAXN], tmp[];
int main()
{
M['A'] = ; M['G'] = ; M['C'] = ; M['T'] = ;
while(scanf("%s",s+)!=EOF)
{
memset(bit, , sizeof(bit));
for(int len = ; len<=; len++)
for(int i = ; s[i]; i++)
bit[len][i%len][M[s[i]]].add(i,); int m, op, l, r;
scanf("%d",&m);
while(m--)
{
scanf("%d",&op);
if(op==)
{
scanf("%d%s",&l,&tmp);
for(int len = ; len<=; len++)
{
bit[len][l%len][M[s[l]]].add(l,-);
bit[len][l%len][M[tmp[]]].add(l,);
}
s[l] = tmp[];
}
else
{
int sum = ;
scanf("%d%d%s",&l,&r,tmp);
int len = strlen(tmp);
for(int i = ; i<len; i++)
sum += bit[len][(l+i)%len][M[tmp[i]]].getsum(l,r);
printf("%d\n", sum);
}
}
}
}
Codeforces - 828E DNA Evolution —— 很多棵树状数组的更多相关文章
- CodeForces 828E DNA Evolution(树状数组)题解
题意:给你一个串k,进行两个操作: “1 a b”:把a位置的字母换成b “2 l r s”:求l到r有多少个字母和s匹配,匹配的条件是这样:从l开始无限循环s形成一个串ss,然后匹配ss和指定区间的 ...
- Codeforces Round #590 (Div. 3)【D题:26棵树状数组维护字符出现次数】
A题 题意:给你 n 个数 , 你需要改变这些数使得这 n 个数的值相等 , 并且要求改变后所有数的和需大于等于原来的所有数字的和 , 然后输出满足题意且改变后最小的数值. AC代码: #includ ...
- Codeforces Round #590 (Div. 3)【D题:维护26棵树状数组【好题】】
A题 题意:给你 n 个数 , 你需要改变这些数使得这 n 个数的值相等 , 并且要求改变后所有数的和需大于等于原来的所有数字的和 , 然后输出满足题意且改变后最小的数值. AC代码: #includ ...
- A Simple Problem with Integers(100棵树状数组)
A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others) Memory Limit: 32768/32768 K ...
- Educational Codeforces Round 10 D. Nested Segments (树状数组)
题目链接:http://codeforces.com/problemset/problem/652/D 给你n个不同的区间,L或者R不会出现相同的数字,问你每一个区间包含多少个区间. 我是先把每个区间 ...
- Codeforces Gym 100114 H. Milestones 离线树状数组
H. Milestones Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descripti ...
- Codeforces Gym 100269F Flight Boarding Optimization 树状数组维护dp
Flight Boarding Optimization 题目连接: http://codeforces.com/gym/100269/attachments Description Peter is ...
- Codeforces 570D TREE REQUESTS dfs序+树状数组 异或
http://codeforces.com/problemset/problem/570/D Tree Requests time limit per test 2 seconds memory li ...
- Codeforces 786C Till I Collapse(树状数组+扫描线+倍增)
[题目链接] http://codeforces.com/contest/786/problem/C [题目大意] 给出一个数列,问对于不同的k,将区间划分为几个, 每个区间出现不同元素个数不超过k时 ...
随机推荐
- Strut2流程分析-----从请求到Action方法()
手写请求会通过strutsPrepareAndExcuteFliter的doFilter()方法 然后会调用StrutsActionProxy类的excute()方法,生成一个代理类(ActionPr ...
- 遇到的问题mongodb
1.MongoNetworkError:failed to connect to server? 数据库没有启动,启动mongo数据库就好 2.有些东西真的是要做好记录的,单纯为了自己日后可以查阅比较 ...
- linux查看硬件信息的方法
目前会Linux的人不少,但是精通的不多,怎样才能做一个符合企业需求的Linux人才,首先要有良好的Linux基础知识.本文为你讲解Linux的知识,今天所讲的是 Linux硬件信息怎样查看,希望你能 ...
- closure--- 闭包与并行运算
闭包有效的减少了函数所需定义的参数数目.这对于并行运算来说有重要的意义.在并行运算的环境下,我们可以让每台电脑负责一个函数,然后将一台电脑的输出和下一台电脑的输入串联起来.最终,我们像流水线一样工 ...
- [译]关于JavaScript 作用域你想知道的一切
原文连接 在学习js的过程对闭包什么的,理解不好,偶然搜到这篇文章.豁然开朗,随翻译. Javacript 中有一系列作用域的概念.对于新的JS的开发人员无法理解这些概念,甚至一些经验丰富的开发者也未 ...
- 【react redux && flux】
redux: http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_three_react-redux.html https://bai ...
- kubernetes安全认证相关资料
1.Kubernetes安装之创建Kubeconfig文件 https://jimmysong.io/blogs/kubernetes-create-kubeconfig/ 2.轻松了解Kuberne ...
- python迟邦定
1.绑定 将函数体和函数调用关联起来,就叫绑定 2.迟绑定 在程序运行之前(也就是编译和链接时)执行的绑定是早绑定,迟绑定(late binding)是发生在运行时. 3.实例说明 def outer ...
- 永远也记不住的linux环境变量,库文件,头文件,交叉编译...
一.环境变量1.node-v4.9.1-linux-armv7l1)安装cp node-v4.9.1-linux-armv7l.tar.gz /usr/local/cd /usr/local/tar ...
- php内存溢出,出现Allowed memory size of 8388608 bytes exhausted错误的解决办法
是因为php页面消耗的最大内存默认是为128M (在PHP的ini件里可以看到) ,如果文件太大或图片太大在读取的时候会发生上述错误. 解决办法: 1.修改 php.ini 将memory_limit ...