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时 ...
随机推荐
- maven POM —— maven权威指南学习笔记(五)
1. 简介 Archetype插件通过 pom.xml 文件创建了一个项目.这就是项目对象模型 (POM),一个项目的声明性描述. 当Maven运行一个目标的时候,每个目标都会访问定 义在项目POM里 ...
- Chrome cookies folder
w本地存储数据2种形式. http://superuser.com/questions/292952/chrome-cookies-folder-in-windows-7 chrome://setti ...
- Python爬虫实例(二)使用selenium抓取斗鱼直播平台数据
程序说明:抓取斗鱼直播平台的直播房间号及其观众人数,最后统计出某一时刻的总直播人数和总观众人数. 过程分析: 一.进入斗鱼首页http://www.douyu.com/directory/all 进入 ...
- 前端开发 - HTML - 总结
html head标签 title 显示网站的标题 meta 提供有关页面的原信息 link 链接css资源文件.网站图标 style 定义内部样式表 script 链接脚本js文件 body标签 块 ...
- 三.插入和查找MySQL记录 数据类型
1.插入数据的两种方式 1)INSERT tb1 VALUES('TOM',25,1863.25); 2)INSERT tb1(username,salary) VALUES('John',4500. ...
- Ubentu下安装Docker
具体可以查看Docker官网,我是在服务器上面操作 1,sudo apt-get install -y apt-transport-https ca-certificates curl softwar ...
- Redis 搜索引擎优化
场景 大家如果是做后端开发的,想必都实现过列表查询的接口,当然有的查询条件很简单,一条 SQL 就搞定了,但有的查询条件极其复杂,再加上库表中设计的各种不合理,导致查询接口特别难写,然后加班什么的就不 ...
- hadoop-3.0.0-beta1分布式安装
楼主是从Hadoop2.x版本过来的,在工作之余自己搭建了一套3.0的版本来耍一耍,此文章的前置环境准备工作省略.主要介绍一些和Hadoop2.x版本不同的安装之处 Hadoop版本:hadoop-3 ...
- 深入理解Oracle调试事件:10046事件详解
10046事件是SQL_TRACE的扩展,被戏称为"吃了兴奋剂的SQL_TRACE" 有效的追踪级别: ① 0级:SQL_TRACE=FASL ...
- day5-正则表达式 re
re模块用于对python的正则表达式的操作. 字符: . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线或汉字 \s 匹配任意的空白符 \d 匹配数字 \b 匹配单词的开始或结束 ^ 匹配 ...