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 ...
随机推荐
- Asp.net Core认证和授权:Cookie认证
关于asp.net core 的文章,博客园已经有很多大牛写过了. 这里我只是记录下自己在学习中的点滴和一些不懂的地方 Cookie一般是用户网站授权,当用户访问需要授权(authorization) ...
- MySQL编码问题探究
占个坑. 今天在向本机搭建的MySQL数据库插入中文的时候报错了. 使用 show variables like 'char%'; 及 show variables like 'collation%' ...
- 软工网络15团队作业4——Alpha阶段敏捷冲刺3.0
软工网络15团队作业4--Alpha阶段敏捷冲刺3.0 1.每天举行站立式会议,提供当天站立式会议照片一张. 2.项目每个成员的昨天进展.存在问题.今天安排. 成员 昨天已完成 今天计划完成 郭炜埕 ...
- Linux 查看磁盘或文件夹及文件大小
当磁盘大小超过标准时会有报警提示,这时如果掌握df和du命令是非常明智的选择. df可以查看一级文件夹大小.使用比例.档案系统及其挂入点,但对文件却无能为力. du可以查看文件及文件夹的大小. ...
- 【转】通过Excel生成批量SQL语句,处理大量数据
经常会遇到这样的要求:用户给发过来一些数据,要我们直接给存放到数据库里面,有的是Insert,有的是Update等等,少量的数据我们可以采取最原始的办法,也就是在SQL里面用Insert into来实 ...
- 【Linux学习五】文本处理
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 一.cut:显示切割的行数据f:选择显示的列s:不显示没有分隔符的行d ...
- Redis 的 5 个常见应用场景
前言Redis 是一个强大的内存型存储,具有丰富的数据结构,使其可以应用于很多方面,包括作为数据库.缓存.消息队列等等. 如果你的印象中Redis只是一个 key-value 存储,那就错过了Redi ...
- Firefox 功能笔记
1.复制标签 说明:复制标签功能即新开一个与当前页一样的标签页,这个功能在Chrome中点击标签右键复制即可,但是在firefox中没有 Firefox中实现:Ctrl+拖动标签页
- 转:判断Caps Lock键是否打开,如果打开则关闭
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- Spring SpringBoot和SpringCloud的关系
Spring SpringBoot和SpringCloud的关系 Spring Cloud 是完全基于 Spring Boot 而开发,Spring Cloud 利用 Spring Boot 特性整合 ...