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的更多相关文章

  1. Poj 3468-A Simple Problem with Integers 线段树,树状数组

    题目:http://poj.org/problem?id=3468   A Simple Problem with Integers Time Limit: 5000MS   Memory Limit ...

  2. POJ A Simple Problem with Integers 线段树 lazy-target 区间跟新

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 105742 ...

  3. POJ 3468A Simple Problem with Integers(线段树区间更新)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 112228 ...

  4. 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 ...

  5. poj 3468A Simple Problem with Integers

    Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...

  6. POJ A Simple Problem with Integers | 线段树基础练习

    #include<cstdio> #include<algorithm> #include<cstring> typedef long long ll; #defi ...

  7. POJ 3468_A Simple Problem with Integers(树状数组)

    完全不知道该怎么用,看书稍微懂了点. 题意: 给定序列及操作,求区间和. 分析: 树状数组可以高效的求出连续一段元素之和或更新单个元素的值.但是无法高效的给某一个区间的所有元素同时加个值. 不能直接用 ...

  8. POJ 3468_A Simple Problem with Integers(线段树)

    题意: 给定序列及操作,求区间和. 分析: 线段树,每个节点维护两个数据: 该区间每个元素所加的值 该区间元素和 可以分为"路过"该区间和"完全覆盖"该区间考虑 ...

  9. poj 3468:A Simple Problem with Integers(线段树,区间修改求和)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 58269   ...

  10. 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 ...

随机推荐

  1. Jquery.Datatables 结合时间段查询,daterangepicker实现Datatables表格带参数查询

      参考:http://datatables.club/example/user_share/send_extra_param.html   下载地址:http://pan.baidu.com/s/1 ...

  2. C#的反射机制

    using System; using System.Collections; using System.Collections.Generic; using System.IO; using Sys ...

  3. 攻城狮在路上(叁)Linux(二十五)--- linux内存交换空间(swap)的构建

    swap的功能是应付物理内存不足的状况,用硬盘来暂时放置内存中的信息. 对于一般主机,物理内存都差不多够用,所以也就不会用到swap,但是对于服务器而言,当遇到大量网络请求时或许就会用到. 当swap ...

  4. android 相对布局里面的一些属性

    一.   有关于RelativeLayout布局的一些属性 1.  相对于兄弟控件的位置:android:layout_below Android:layout_toLeftof Android:la ...

  5. loj 1271

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26981 思路:题目的意思是求给定的起点到终点的最短路径序列,并且这 ...

  6. Linux之find命令用于统计信息

    1. 计算当前目录中的文件数: [root@localhost tmp]# find . -type f | wc -l 2. 查找/etc目录中最新的和最旧的文件,以文件时间排序并按年-月-日的格式 ...

  7. thinkphp数据表操作恐怖事件。

    1当使用thinkphp的where(array())时,如果里面的字段在数据库是没有的,则默认这个条件为1,这时就可能出现大批修改记录问题.如修改所有用户的密码.特别要注意的是,这里的表字段是区分大 ...

  8. loadrunner怎么将变量保存到参数中

    用这个lr_save_string 函数 char *b = "很简单";lr_save_string(b,"b"); lr_output_message(&q ...

  9. PS切图的几种方式

    方法一 点击图层右键-->导出为 导出需要的格式与大小 方法二 选择多个图层右键--->快速导出为PNG(导出的名字就是图层名字) 方法三

  10. JDK BIO编程

    网络编程的基本模型是Client/Server模型,也就是两个进程之间进行相互通信,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端通过连接操作向服务端监听的地址发起连接请求,通过三次握手建 ...