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时 ...
随机推荐
- Javaweb Tomcat 项目部署方式
一.静态部署 1.直接将web项目文件件拷贝到webapps 目录中 Tomcat的Webapps目录是Tomcat默认的应用目录,当服务器启动时,会加载所有这个目录下的应用.所以可以将JSP ...
- /proc/iomem和/proc/ioports对应的fops
/proc/iomem和/proc/ioports对应的fops static int __init ioresources_init(void) { struct proc_dir_entr ...
- sql语句的安全性考虑
sql语句的应该考虑哪些安全性呢? 1.防止sql注入,对特殊字符进行转义(addslashes),或者使用已经编译好的sql语句进行变量的绑定: 2.当sql运行出现错误的时候,不要把数据库返回的错 ...
- 如何缩减手游app安装包的大小?
包体过大对手游的影响更是诟病已久,有具体数据证明,游戏包体越大,在游戏运营推广过程中游戏用户的转化率就越低:反之,游戏包体越小,游戏用户的下载转化率就越高(如下图),所有的手机app.游戏在大版本更新 ...
- python模块之PIL模块(生成随机验证码图片)
PIL简介 什么是PIL PIL:是Python Image Library的缩写,图像处理的模块.主要的类包括Image,ImageFont,ImageDraw,ImageFilter PIL的导入 ...
- redis之django-redis
自定义连接池 这种方式跟普通py文件操作redis一样,代码如下: views.py import redis from django.shortcuts import render,HttpResp ...
- 003-maven简介
1.1简介 Maven,只是的积累,专家或内行 Maven是优秀的构建工具,依赖管理工具,项目信息管理工具,跨平台.提供了中央仓库,自动下载构件. 1.通过坐标系统定位每一个构件(artifact), ...
- Oracle中to_number()函数的用法
to_number()函数是oracle中常用的类型转换函数之一,是将一些处理过的按一定格式编排过的字符串变回数值型的格式. 1.to_number()函数可以将char或varchar2类型的str ...
- Spring框架第二篇之Bean的装配
一.默认装配方式 代码通过getBean();方式从容器中获取指定的Bean实例,容器首先会调用Bean类的无参构造器,创建空值的实例对象. 举例: 首先我在applicationContext.xm ...
- (转)CreateThread与_beginthread,内存泄漏为何因(原帖排版有些不好 ,所以我稍微整理下)
在写c++代码时,一直牢记着一句话:决不应该调用CreateThread. 应该使用Visual C++运行时库函数_beginthreadex.好像CreateThread函数就 ...