POJ-A Simple Problem with Integers
Description
给出了一个序列,你需要处理如下两种询问。
"C a b c"表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000)。
"Q a b" 询问[a, b]区间中所有值的和。
Input
第一行包含两个整数N, Q。1 ≤ N,Q ≤ 100000.
第二行包含n个整数,表示初始的序列A (-1000000000 ≤ Ai ≤ 1000000000)。
接下来Q行询问,格式如题目描述。
Output
对于每一个Q开头的询问,你需要输出相应的答案,每个答案一行。
Sample Input
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
Sample Output
4
55
9
15 这个题搞了不少时间,主要是难懂,而且写代码稍微快一点就 各种错误,吓得我不敢写快了,以后还是要多多细心才行。 这道题用开始那种线段树已经不行了,必须想出效率更高的方法,于是延迟标记出来了,用sign数组表示,它主要用于记录目前更新或者查询到的节点,并且它很懒,不更新未到节点,直到某次查询或者更新到标记的节点的子节点时
这个时候就把当前节点更新了,去掉节点标记时需要把子节点标记。 此次代码重点:区间更新,延迟标记
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#include<algorithm>
using namespace std; #define INF 0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 const int MX = 100050;
long long sum[MX<<2];
long long sign[MX<<2];
int T, n, Q, X, Y;
long long Z; void PushUp(int rt) {
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void PushDown(int rt, int len) {
if (sign[rt]) {
sign[rt<<1] += sign[rt];
sign[rt<<1|1] += sign[rt];
sum[rt<<1] += (len - (len>>1)) * sign[rt];//为了解决奇数所带来的子节点分配不平衡问题,因此需要这样做
sum[rt<<1|1] += (len>>1) * sign[rt];
sign[rt] = 0;
}
}
void Build(int l, int r, int rt) {
sign[rt] = 0;//初始化标记
if (l == r) {
scanf("%lld", &sum[rt]);
return ;
}
int m = (l + r)>>1;
Build(lson);
Build(rson);
PushUp(rt);
}
void Update(int L, int R, long long z, int l, int r, int rt) {
if (L <= l && r <= R) {
sign[rt] += z;//记录下更新的值
sum[rt] += z * (r - l + 1);//批量更新
return ;
}
PushDown(rt, r - l + 1);//检查标记,看是否需要继续向下更新
int m = (l + r)>>1;
if (L <= m) Update(L, R, z, lson);
if (R > m) Update(L, R, z, rson);
PushUp(rt);
}
long long Query(int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) {
return sum[rt];
}
PushDown(rt, r - l + 1);//别忘了查询时也要注意标记是否存在
int m = (l + r)>>1;
long long ret = 0;
if (L <= m) ret += Query(L, R, lson);
if (R > m) ret += Query(L, R, rson);
return ret;
}
int main() {
//freopen("input.txt", "r", stdin);
while (scanf("%d %d\n", &n, &Q) != EOF) {
Build(1, n, 1);
while (Q--) {
char op[2];
scanf("%s", op);
if (op[0] == 'Q') {
scanf("%d %d", &X, &Y);
long long ans = Query(X, Y, 1, n, 1);
printf("%lld\n", ans);
} else {
scanf("%d %d %lld", &X, &Y, &Z);
Update(X, Y, Z, 1, n, 1);
}
}
}
return 0;
}
POJ-A Simple Problem with Integers的更多相关文章
- Poj 3468-A Simple Problem with Integers 线段树,树状数组
题目:http://poj.org/problem?id=3468 A Simple Problem with Integers Time Limit: 5000MS Memory Limit ...
- POJ A Simple Problem with Integers 线段树 lazy-target 区间跟新
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 105742 ...
- POJ 3468A Simple Problem with Integers(线段树区间更新)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 112228 ...
- POJ - 3468A Simple Problem with Integers (线段树区间更新,区间查询和)
You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of op ...
- poj 3468A Simple Problem with Integers
Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...
- POJ A Simple Problem with Integers | 线段树基础练习
#include<cstdio> #include<algorithm> #include<cstring> typedef long long ll; #defi ...
- POJ 3468_A Simple Problem with Integers(树状数组)
完全不知道该怎么用,看书稍微懂了点. 题意: 给定序列及操作,求区间和. 分析: 树状数组可以高效的求出连续一段元素之和或更新单个元素的值.但是无法高效的给某一个区间的所有元素同时加个值. 不能直接用 ...
- POJ 3468_A Simple Problem with Integers(线段树)
题意: 给定序列及操作,求区间和. 分析: 线段树,每个节点维护两个数据: 该区间每个元素所加的值 该区间元素和 可以分为"路过"该区间和"完全覆盖"该区间考虑 ...
- poj 3468:A Simple Problem with Integers(线段树,区间修改求和)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 58269 ...
- poj 3468 A Simple Problem with Integers 线段树第一次 + 讲解
A Simple Problem with Integers Description You have N integers, A1, A2, ... , AN. You need to deal w ...
随机推荐
- Git撤销提交和修改相关操作
团队开发中经常遇到错误删除文件,错误提交等情况,那么使用Git该如何正确的进行撤销和恢复呢? 一.增补提交 git commit –C HEAD –a --amend -C表示复用指定提交的提交留言, ...
- Linux性能分析工具的安装和使用
转自:http://blog.chinaunix.net/uid-26488891-id-3118279.html Normal 0 7.8 磅 0 2 false false false EN-US ...
- Delphi字符串的基本操作与常用函数
参考:http://www.cnblogs.com/pchmonster/archive/2011/12/16/2290034.html 结合这个博客一起学习:http://www.cnblogs.c ...
- Delphi的属性Property
参考:http://www.cnblogs.com/edisonfeng/archive/2012/05/22/2513727.html 一.基本属性 TOnUserInfoShow = proced ...
- 跳出IFrame几种方式
1. <script type="text/javascript"> if (top.location !== self.location) { top.locatio ...
- 【JAVA使用XPath、DOM4J解析XML文件,实现对XML文件的CRUD操作】
一.简介 1.使用XPath可以快速精确定位指定的节点,以实现对XML文件的CRUD操作. 2.去网上下载一个“XPath帮助文档”,以便于查看语法等详细信息,最好是那种有很多实例的那种. 3.学习X ...
- 命令行登陆Oracle(包括远程登陆)
本方法适用于在cmd命令行窗口以及pl/sql登陆Oracle下登录本机或者远程Oracle. 1.首先保证在当前主机上设置了ORACLE_HOME环境变量: 例如:ORACLE_HOME=D ...
- js或jquery实现页面打印可局部打印
方法一:直接用js的打印方法 <input id="btnPrint" type="button" value="打印" onclic ...
- SQL常见错误及处理方法
1.情况:数据库引擎安装失败,报类似权限不足的错误 解决:可能由于计算机名和用户名相同导致,更改计算机名,卸载干净重装即可
- Asp.Net MVC中DropDownListFor的用法
在Asp.Net MVC中可以用DropDownListFor的方式来让用户选择已定列表中的一个数值.用法不复杂,这里简单做一个记录. 首先我们要定义一个 Model ,用户在 DropDownLis ...