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 ...
随机推荐
- php函数addslashes()使用方法详解
实例 在每个双引号(")前添加反斜杠: <?php $str = addslashes('Shanghai is the "biggest" city in Chi ...
- node.js初识06
node中的fs文件系统 var http = require("http"); var fs = require("fs"); var server = ht ...
- LocalStorage存储和cookie存储
localStorage是H5的新特性,主要用来本地存储,一般浏览器支持的大小是5M,不同浏览器会有所不同,解决了cookie存储空间不足的问题. 2.使用: ⑴.存 if(!window.l ...
- MySQL.配置MariaDB的字符集
配置MariaDB的字符集 环境: 操作系统:CentOS Linux release 7.x mariadb安装及配置 yum install mariadb-server mariadb #安装 ...
- sql语句,加引号和不加引号的区别
今天碰到个问题,查询数据的时候,显示表不存在,在可视化窗口确实能看见.试着给表名加个引号,发现能成功查询数据了.上网查询原因如下: 1.oracle表和字段是有大小写的区别.oracle默认是大写,如 ...
- Android -- 自定义ViewGroup实现FlowLayout效果
1,在开发的时候,常在我们的需求中会有这种效果,添加一个商品的一些热门标签,效果图如下: 2,从上面效果可以看得出来,这是一个自定义的ViewGroup,然后实现换行效果,让我们一起来实现一下 自定义 ...
- Lua之math
Lua之math函数: 转载请注明出处:http://www.cnblogs.com/jietian331/p/8032555.html abs 取绝对值 math.abs(-15) 15 acos ...
- [12]Windows内核情景分析 --- MDI
Mdl意为'内存映射描述符'.'缓冲描述符',一个mdl就代表一个缓冲.(任意一块物理内存,可以同时映射到用户地址空间和系统地址空间的) 设备IO方式分为三种:缓冲方式.直接IO方式.直接方式 缓冲方 ...
- Python读取excel数据类型处理
一.python xlrd读取datetime类型数据:https://blog.csdn.net/y1535766478/article/details/78128574 (1)使用xlrd读取出来 ...
- scrapy:get cookie from response
scrapy shell fetch('your_url') response.headers.getlist("Set-Cookie")https://stackoverflow ...