Codeforces 438D The Child and Sequence - 线段树
At the children's day, the child came to Picks's house, and messed his house up. Picks was angry at him. A lot of important things were lost, in particular the favorite sequence of Picks.
Fortunately, Picks remembers how to repair the sequence. Initially he should create an integer array a[1], a[2], ..., a[n]. Then he should perform a sequence of m operations. An operation can be one of the following:
- Print operation l, r. Picks should write down the value of
. - Modulo operation l, r, x. Picks should perform assignment a[i] = a[i] mod x for each i (l ≤ i ≤ r).
- Set operation k, x. Picks should set the value of a[k] to x (in other words perform an assignment a[k] = x).
Can you help Picks to perform the whole sequence of operations?
The first line of input contains two integer: n, m (1 ≤ n, m ≤ 105). The second line contains n integers, separated by space: a[1], a[2], ..., a[n] (1 ≤ a[i] ≤ 109) — initial value of array elements.
Each of the next m lines begins with a number type
.
- If type = 1, there will be two integers more in the line: l, r (1 ≤ l ≤ r ≤ n), which correspond the operation 1.
- If type = 2, there will be three integers more in the line: l, r, x (1 ≤ l ≤ r ≤ n; 1 ≤ x ≤ 109), which correspond the operation 2.
- If type = 3, there will be two integers more in the line: k, x (1 ≤ k ≤ n; 1 ≤ x ≤ 109), which correspond the operation 3.
For each operation 1, please print a line containing the answer. Notice that the answer may exceed the 32-bit integer.
5 5 1 2 3 4 5 2 3 5 4 3 3 5 1 2 5 2 1 3 3 1 1 3
8 5
10 10 6 9 6 7 6 1 10 10 9 5 1 3 9 2 7 10 9 2 5 10 8 1 4 7 3 3 7 2 7 9 9 1 2 4 1 6 6 1 5 9 3 1 10
49 15 23 1 9
Consider the first testcase:
- At first, a = {1, 2, 3, 4, 5}.
- After operation 1, a = {1, 2, 3, 0, 1}.
- After operation 2, a = {1, 2, 5, 0, 1}.
- At operation 3, 2 + 5 + 0 + 1 = 8.
- After operation 4, a = {1, 2, 2, 0, 1}.
- At operation 5, 1 + 2 + 2 = 5.
题目大意 维护一个数列,有3种操作,分别是区间求和,区间取模和单点修改。
显然线段树(请不要问我为什么。。。学长的Tag打在那儿的)
区间求和和单点修改都是线段树的拿手好戏,但是对于区间取模似乎不是那么好做。考虑可以区间批量更新sum吗?显然不行。
但是考虑到这里只有单点修改,而且对一个大于模数的数取模,它的值至多为它原来的值的一半。
所以区间记录一个最大值剪枝,每次区间取模先判断是否有必要进行递归取模,如果有,就暴力递归下去,在底层修改。
Code
/**
* Codeforces
* Problem#438D
* Accepted
* Time: 436ms
* Memory: 8740k
*/
#include <bits/stdc++.h>
#ifndef WIN32
#define Auto "%lld"
#else
#define Auto "%I64d"
#endif
using namespace std; typedef class SegTreeNode {
public:
int maxv;
long long sum;
SegTreeNode *l, *r; SegTreeNode():maxv(), sum(), l(NULL), r(NULL) { } inline void pushUp() {
maxv = max(l->maxv, r->maxv);
sum = l->sum + r->sum;
}
}SegTreeNode; typedef class SegTree {
public:
SegTreeNode* root; SegTree():root(NULL) { }
SegTree(int n, int* a) {
build(root, , n, a);
} void build(SegTreeNode*& node, int l, int r, int* a) {
node = new SegTreeNode();
if(l == r) {
node->sum = node->maxv = a[l];
return;
}
int mid = (l + r) >> ;
build(node->l, l, mid, a);
build(node->r, mid + , r, a);
node->pushUp();
} void update(SegTreeNode*& node, int l, int r, int idx, int val) {
if(l == r) {
node->maxv = node->sum = val;
return;
}
int mid = (l + r) >> ;
if(idx <= mid) update(node->l, l, mid, idx, val);
else update(node->r, mid + , r, idx, val);
node->pushUp();
} void update(SegTreeNode*& node, int l, int r, int ql, int qr, int moder) {
if(l == r) {
node->maxv = (node->sum %= moder);
return;
}
int mid = (l + r) >> ;
if(qr <= mid && node->l->maxv >= moder) update(node->l, l, mid, ql, qr, moder);
else if(ql > mid && node->r->maxv >= moder) update(node->r, mid + , r, ql, qr, moder);
else if(qr > mid && ql <= mid) {
if(node->l->maxv >= moder)
update(node->l, l, mid, ql, mid, moder);
if(node->r->maxv >= moder)
update(node->r, mid + , r, mid + , qr, moder);
}
node->pushUp();
} long long query(SegTreeNode*& node, int l, int r, int ql, int qr) {
if(l == ql && r == qr) {
return node->sum;
}
int mid = (l + r) >> ;
if(qr <= mid) return query(node->l, l, mid, ql, qr);
if(ql > mid) return query(node->r, mid + , r, ql, qr);
return query(node->l, l, mid, ql, mid) + query(node->r, mid + , r, mid + , qr);
}
}SegTree; int n, m;
int* arr;
SegTree st;
inline void init() {
scanf("%d%d", &n, &m);
arr = new int[(n + )];
for(int i = ; i <= n; i++)
scanf("%d", arr + i);
st = SegTree(n, arr);
} inline void solve() {
int opt, a, b, c;
while(m--) {
scanf("%d%d%d", &opt, &a, &b);
if(opt == ) {
printf(Auto"\n", st.query(st.root, , n, a, b));
} else if(opt == ) {
scanf("%d", &c);
st.update(st.root, , n, a, b, c);
} else {
st.update(st.root, , n, a, b);
}
}
} int main() {
init();
solve();
return ;
}
Codeforces 438D The Child and Sequence - 线段树的更多相关文章
- CodeForces 438D The Child and Sequence (线段树 暴力)
传送门 题目大意: 给你一个序列,要求在序列上维护三个操作: 1)区间求和 2)区间取模 3)单点修改 这里的操作二很讨厌,取模必须模到叶子节点上,否则跑出来肯定是错的.没有操作二就是线段树水题了. ...
- CF(438D) The Child and Sequence(线段树)
题意:对数列有三种操作: Print operation l, r. Picks should write down the value of . Modulo operation l, r, x. ...
- 2018.07.23 codeforces 438D. The Child and Sequence(线段树)
传送门 线段树维护区间取模,单点修改,区间求和. 这题老套路了,对一个数来说,每次取模至少让它减少一半,这样每次单点修改对时间复杂度的贡献就是一个log" role="presen ...
- Codeforces Round #250 (Div. 1) D. The Child and Sequence 线段树 区间取摸
D. The Child and Sequence Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest ...
- Codeforces Round #250 (Div. 1) D. The Child and Sequence 线段树 区间求和+点修改+区间取模
D. The Child and Sequence At the children's day, the child came to Picks's house, and messed his h ...
- 题解——CodeForces 438D The Child and Sequence
题面 D. The Child and Sequence time limit per test 4 seconds memory limit per test 256 megabytes input ...
- cf250D. The Child and Sequence(线段树 均摊复杂度)
题意 题目链接 单点修改,区间mod,区间和 Sol 如果x > mod ,那么 x % mod < x / 2 证明: 即得易见平凡, 仿照上例显然, 留作习题答案略, 读者自证不难. ...
- Codeforces Round #250 (Div. 1) D. The Child and Sequence (线段树)
题目链接:http://codeforces.com/problemset/problem/438/D 给你n个数,m个操作,1操作是查询l到r之间的和,2操作是将l到r之间大于等于x的数xor于x, ...
- Codeforces 438D The Child and Sequence
题意:给定一个n个数的序列,完成以下3个操作: 1.给定区间求和 2.给定区间对x取模 3.单点修改 对一个数取模,这个数至少折半.于是我们记一个最大值max,如果x>max则不做处理. #in ...
随机推荐
- 读书笔记_Effective C++_条款一:将C++视为一个语言联邦
C++起源于C,最初的名称为C with Classes,意为带类的C语言,然而,随着C++的不断发展和壮大,在很多功能上已经远远超越了C,甚至一些C++程序员反过来看C代码会觉得不习惯. C++可以 ...
- UVA 10256 The Great Divide(点在多边形内)
The Great Divid [题目链接]The Great Divid [题目类型]点在多边形内 &题解: 蓝书274, 感觉我的代码和刘汝佳的没啥区别,可是我的就是wa,所以贴一发刘汝佳 ...
- Jenkins. 安装过程中出现一个错误: No such plugin: cloudbees-folder
安装过程中出现一个错误: No such plugin: cloudbees-folder 安装插件,有时候会报类似的错误:An error occurred during installation: ...
- LeetCode35.搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引.如果目标值不存在于数组中,返回它将会被按顺序插入的位置. 你可以假设数组中无重复元素. 示例 1: 输入: [1,3,5,6], 5 输 ...
- 关于toolchain(工具链)的一点知识
之前一直觉得toolchain是个高大上的东西,现摘录 uClibc中的FAQ以助理解. A toolchain consists of GNU binutils, the gcc compiler, ...
- 软件常用设置(VC, eclipse ,nodejs)---自己备用
留存复制使用 1.VC ----1.1VC项目设置 输出目录: $(SolutionDir)../bin/$(platform)/$(Configuration) $(ProjectDir)../bi ...
- GGTalk即时通讯系统(支持广域网)终于有移动端了!(技术原理、实现、源码)
首先要感谢大家一直以来对于GGTalk即时通讯系统的关注和支持!GGTalk即时通讯系统的不断完善与大家的支持分不开! 从2013年最初的GG1.0开放源码以来,到后来陆续增加了网盘功能.远程协助功能 ...
- Java8的CompletionService使用与原理
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/ShiJiaqi. https://www.cnblogs.com/shijiaqi1066/p/1045423 ...
- 基于FPGA摄像头图像采集显示系统
本系统主要由FPGA主控模块.图像采集模块.图像存储模块以及图像显示模块等模块组成.其中图像采集模块选择OV7670摄像头模块,完成对视频图像的采集和解码功能,并以RGB565标准输出RGB 5:6: ...
- GLSL写vertex shader和fragment shader
0.一般来说vertex shader处理顶点坐标,然后向后传输,经过光栅化之后,传给fragment shader,其负责颜色.纹理.光照等等. 前者处理之后变成裁剪坐标系(三维),光栅化之后一般认 ...