A Simple Problem with Integers
Time Limit:5000MS   Memory Limit:131072K
Case Time Limit:2000MS

Description

You have N integers, A1A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of AaAa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

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

Hint

The sums may exceed the range of 32-bit integers.
 
题解:本题也是线段树系列的模板题之一,要求的是成段更新+懒惰标记。PS:原题的说明有问题,上面说的“C a b c”中的c的范围其实在int32之外,需要使用long long,否则定是WA,真心坑爹,连WA多次,还是在discuss中看到的原因。
 
稍微讲解下代码中的一些细节: step<<1 与 step<<1|1,意思分别是step*2 和step*+1,具体为什么,可以回去复习一下位运算
 
AC代码如下:
 

 #include <cstdio>
#include <cstring> typedef long long ll;
const int LEN = * ; struct line
{
int left;
int right;
ll value;
ll lazy; //懒惰标记
}line[LEN]; void buildt(int l, int r, int step) //建树初始化
{
line[step].left = l;
line[step].right = r;
line[step].lazy = ;
line[step].value = ;
if (l == r)
return;
int mid = (l + r) / ;
buildt(l, mid, step<<);
buildt(mid+, r, step<<|);
} void pushdown(int step)
{
if (line[step].left == line[step].right) //如果更新到最深处的子节点,返回
return;
if (line[step].lazy != ){ //如果有懒惰标记,向下传递懒惰标记且更新两个子节点的值
line[step<<].lazy += line[step].lazy;
line[step<<|].lazy += line[step].lazy;
line[step<<].value += (line[step<<].right - line[step<<].left + ) * line[step].lazy;
line[step<<|].value += (line[step<<|].right - line[step<<|].left + ) * line[step].lazy;
line[step].lazy = ;
}
} void update(int l, int r, ll v, int step)
{
line[step].value += v * (r-l+); //更新到当前节点,就在当前节点的value中加上增加的值
pushdown(step);
if (line[step].left == l && line[step].right == r){ //如果到达目标线段,做上懒惰标记,返回
line[step].lazy = v;
return;
}
int mid = (line[step].left + line[step].right) / ;
if (r <= mid)
update(l, r, v, step<<);
else if (l > mid)
update(l, r, v, step<<|);
else{
update(l, mid, v, step<<);
update(mid+, r, v, step<<|);
}
} ll findans(int l, int r, int step)
{
if (l == line[step].left && r == line[step].right) //如果找到目标线段,返回值
return line[step].value;
pushdown(step);
int mid = (line[step].left + line[step].right) / ;
if (r <= mid)
return findans(l, r, step<<);
else if (l > mid)
return findans(l, r, step<<|);
else
return findans(l, mid, step<<) + findans(mid+, r, step<<|);
} int main()
{
//freopen("in.txt", "r", stdin);
int n, q;
scanf("%d %d", &n, &q);
buildt(, n, );
for(int i = ; i <= n; i++){
ll t;
scanf("%I64d", &t);
update(i, i, t, );
}
for(int i = ; i < q; i++){
char query[];
scanf("%s", query);
if (query[] == 'C'){
int a, b;
ll c;
scanf("%d %d %I64d", &a, &b, &c);
update(a, b, c, );
}
else if (query[] == 'Q'){
int a, b;
scanf("%d %d", &a, &b);
printf("%I64d\n", findans(a, b, ));
}
}
return ;
}

【POJ】3468 A Simple Problem with Integers ——线段树 成段更新 懒惰标记的更多相关文章

  1. POJ 3468 A Simple Problem with Integers (线段树成段更新)

    题目链接:http://poj.org/problem?id=3468 题意就是给你一组数据,成段累加,成段查询. 很久之前做的,复习了一下成段更新,就是在单点更新基础上多了一个懒惰标记变量.upda ...

  2. POJ 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)

    A Simple Problem with Integers [题目链接]A Simple Problem with Integers [题目类型]线段树 成段增减+区间求和 &题解: 线段树 ...

  3. POJ3468_A Simple Problem with Integers(线段树/成段更新)

    解题报告 题意: 略 思路: 线段树成段更新,区间求和. #include <iostream> #include <cstring> #include <cstdio& ...

  4. POJ 3468 线段树 成段更新 懒惰标记

    A Simple Problem with Integers Time Limit:5000MS   Memory Limit:131072K Case Time Limit:2000MS Descr ...

  5. poj 3468 A Simple Problem with Integers 线段树区间加,区间查询和

    A Simple Problem with Integers Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://poj.org/problem?i ...

  6. poj 3468 A Simple Problem with Integers 线段树区间加,区间查询和(模板)

    A Simple Problem with Integers Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://poj.org/problem?i ...

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

  8. [POJ] 3468 A Simple Problem with Integers [线段树区间更新求和]

    A Simple Problem with Integers   Description You have N integers, A1, A2, ... , AN. You need to deal ...

  9. poj 3468 A Simple Problem with Integers (线段树区间更新求和lazy思想)

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

随机推荐

  1. Wpf中MediaElement循环播放

    原文:Wpf中MediaElement循环播放 前一段时间做了一个项目,里面牵涉到媒体文件的循环播放问题,在网上看了好多例子,都是在xaml中添加为MediaElement添加一个TimeLine,不 ...

  2. PV与并发之间换算的算法 换算公式

  3. Minimum Depth of Binary Tree 解答

    Question Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along ...

  4. mysql的主从复制配置

    怎么安装mysql数据库,这里不说了,只说它的主从复制,步骤如下: 1.主从服务器分别作以下操作:  1.1.版本一致  1.2.初始化表,并在后台启动mysql  1.3.修改root的密码 2.修 ...

  5. Virtual Friends(并查集+map)

    Virtual Friends Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  6. C/C++中经常使用的字符串处理函数和内存字符串函数

    一.            字符处理函数 1.        字符处理函数:<ctype.h> int isdigit(int ch) ;//是否为数字,即ch是否是0-9中的字符 int ...

  7. Android系统Surface机制的SurfaceFlinger服务简要介绍和学习计划

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8010977 前面我们从Android应用程序与 ...

  8. linux下挂载iso镜像文件(转)

    挂接命令(mount) 首先,介绍一下挂接(mount)命令的使用方法,mount命令参数非常多,这里主要讲一下今天我们要用到的. 命令格式: mount [-t vfstype] [-o optio ...

  9. Information seeking letter, hard copy version

    23 Roanoke Street Blacksburg, VA 24060 (540) 555-1123 K.Walker@vt.edu October 23, 20XY Mr. James G. ...

  10. dojo.create\dojo.place\dojo.empty\dojo.destroy\dojo.body

    1.dojo.create 1.create a node; 2.set attributes on it;  3.place it in the DOM. dojo.create(/*String| ...