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时 ...
随机推荐
- react 快速 点击
用 fastclick npm 一下 他 就可以
- java WebSocket的实现以及Spring WebSocket
开始学习WebSocket,准备用它来实现一个在页面实时输出log4j的日志以及控制台的日志. 首先知道一些基础信息: java7 开始支持WebSocket,并且只是做了定义,并未实现 tomcat ...
- Convolution Matrix
w褶积矩阵.二值化旧图经核矩阵得到新图. https://docs.gimp.org/en/plug-in-convmatrix.html 8.2. Convolution Matrix 8.2.1. ...
- 使用JCONSOLE远程监控JVM
启动JMS服务 JConsole是从Java 5中开始引入的一个用于对JVM性能和资源消耗进行监控的图形化工具.JConsole可以连接本地的Java程序,也可以连接远程的Java程序.由于是GUI的 ...
- django中同源策略和跨域解决方案
一 同源策略 1.1何谓同源? 如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源. 举个例子: 下表给出了相对http://a.xyz.com/dir/page.html同 ...
- 【我的Android进阶之旅】Android目录过长造成错误:Failed to crunch file abc_textfield_search_activated_mtrl_alpha.9.png
一.编译异常描述 一大早来开发一个新的需求,拉取了一个新的分支,然后导入Android Studio之后,编译就报错了,报错如下所示: 错误具体日志如下所示: Information:Gradle t ...
- DRF的版本、认证、权限
DRF的版本 版本控制是做什么用的, 我们为什么要用 首先我们要知道我们的版本是干嘛用的呢~~大家都知道我们开发项目是有多个版本的~~ 当我们项目越来越更新~版本就越来越多~~我们不可能新的版本出了~ ...
- 服务遇到错误。很可能由IncludeExceptionDetailInFaults=true创建的ExceptionDetail,其值为:System.ArgumentException:指定的值还有无效的控制字符
解决方案:将服务的应用程序池由 集成 修改为 经典.(或者 可以反过来试下.) 环境:WindowsServer2008R2+IIS7.5+WCF 出错样图:
- python学习笔记(二十三)私有方法和私有属性
在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑. 但是,从前面Person类的定义来看,外部代码还是可以自由地修改一个实例的nam ...
- 1130 - Host '' is not allowerd to connect to this MySQL server,
是因为缺少访问权限,在MySQL ->User表里 执行 INSERT INTO `user` VALUES ('%', 'root', '*81F5E21E35407D884A6CD4A731 ...