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 ...
随机推荐
- SQLServer索引
SQLServer索引1.聚集和非聚集索引聚集索引:根据聚集索引进行排序,非聚集索引因为不根据索引键排序,所以聚集索引比非聚集索引快(一个表只有一个聚集索引)2.唯一索引和非唯一索引唯一索引时值不能重 ...
- JavaWeb学习之JSTL自定义标签库的使用、JSTL自定义函数库(7)
一.自定义标签,步骤 * 确定需求 * <my:date /> 输出当前系统的时间 yyyy-MM-dd hh:mm:ss:SSS * 编写Java类 新建包名:com.yxl.tag,新 ...
- jQuery Mobile学习之grid、等待显示的ajax效果、页面跳转、页面跳转传递参数等(二)
Index.cshtml <!-- Start of second page --> <section data-role="page" id="bar ...
- siblings 使用
//$(object).siblings().each(function () { // $(this).find("img").attr("class", & ...
- 攻城狮在路上(叁)Linux(二十)--- Linux磁盘格式化
磁盘完成分区之后,进行格式化,生成文件系统. 命令格式: mkfs [-t 文件系统格式] 设备文件名 <== 使用 mkfs [Tab][Tab] 可以查看linux支持的文件系统格式 示例 ...
- visual studio2010复制粘贴源代码到Word时乱码问题 分类: C# 2014-11-28 09:25 687人阅读 评论(0) 收藏
问题描述: visual studio2010 拷贝源代码的时候,在windows自带的写字板和word2010上,粘贴的时候中文字符都会变成乱码. 如: "该用户已经被成功添加" ...
- PHP利用jquery生成各种验证码和Ajax验证
PHP生成验证码图片 PHP生成验证码的原理:使用PHP的GD库,生成一张带验证码的图片,并将验证码保存在Session中.PHP 生成验证码的大致流程有: .产生一张png的图片: .为图片设置背景 ...
- 在ASP.NET 5中读取配置文件
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 在ASP.NET 5中摒弃了之前配置文件的基础结构,引入了一个全新配置文件系统.今天推荐的文 ...
- 1:A+B Problem
总时间限制: 1000ms 内存限制: 65536kB 描述 Calculate a + b 输入 Two integer a,,b (0 ≤ a,b ≤ 10) 输出 Output a + b ...
- PAT A 1014. Waiting in Line (30)【队列模拟】
题目:https://www.patest.cn/contests/pat-a-practise/1014 思路: 直接模拟类的题. 线内的各个窗口各为一个队,线外的为一个,按时间模拟出队.入队. 注 ...