【POJ】3468 A Simple Problem with Integers ——线段树 成段更新 懒惰标记
Description
You have N integers, A1, A2, ... , 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 A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+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
#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 ——线段树 成段更新 懒惰标记的更多相关文章
- POJ 3468 A Simple Problem with Integers (线段树成段更新)
题目链接:http://poj.org/problem?id=3468 题意就是给你一组数据,成段累加,成段查询. 很久之前做的,复习了一下成段更新,就是在单点更新基础上多了一个懒惰标记变量.upda ...
- POJ 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)
A Simple Problem with Integers [题目链接]A Simple Problem with Integers [题目类型]线段树 成段增减+区间求和 &题解: 线段树 ...
- POJ3468_A Simple Problem with Integers(线段树/成段更新)
解题报告 题意: 略 思路: 线段树成段更新,区间求和. #include <iostream> #include <cstring> #include <cstdio& ...
- POJ 3468 线段树 成段更新 懒惰标记
A Simple Problem with Integers Time Limit:5000MS Memory Limit:131072K Case Time Limit:2000MS Descr ...
- 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 ...
- 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 ...
- 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 ...
- [POJ] 3468 A Simple Problem with Integers [线段树区间更新求和]
A Simple Problem with Integers Description You have N integers, A1, A2, ... , AN. You need to deal ...
- poj 3468 A Simple Problem with Integers (线段树区间更新求和lazy思想)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 75541 ...
随机推荐
- C#开发SQLServer的Geometry和Geography存储
原文:C#开发SQLServer的Geometry和Geography存储 SQL Server2008推出后最大的变化就是提供了支持空间数据存储的Geometry和Geography,这个也是如果将 ...
- 如何从Eclipse导入github上的项目源码
1.首先在github.com上申请一个账号,比如笔者的账号为puma0072.Eclipse需要安装egit插件,在Eclipse中选择help->Marketplace,在search中输入 ...
- Linux下程序崩溃,ulimit,coredump,gdbserver
操作系统:Ubuntu10.04 前言: 在程序崩溃后,如何快速定位问题. 以下方法适用于开发调试阶段,不太适用成品. 本文着眼于嵌入式,PC方面更简单. 核心:gdbserv ...
- bzoj3407 [Usaco2009 Oct]Bessie's Weight Problem 贝茜的体重问题
Description 贝茜像她的诸多姊妹一样,因为从约翰的草地吃了太多美味的草而长出了太多的赘肉.所以约翰将她置于一个及其严格的节食计划之中.她每天不能吃多过H(5≤日≤45000)公斤的干 ...
- LintCode-A + B 用位操作模拟加法
class Solution { public: /* * @param a: The first integer * @param b: The second integer * @return: ...
- libcurl 多线程使用注意事项 - Balder~专栏 - 博客频道 - CSDN.NET
libcurl 多线程使用注意事项 - Balder~专栏 - 博客频道 - CSDN.NET libcurl 多线程使用注意事项 分类: C/C++学习 2012-05-24 18:48 2843人 ...
- c# 高斯模糊
using System; using System.Collections.Generic; using System.Text; using System.Drawing; using Syste ...
- activity之栈管理
在android中.一个activity组件能够激活还有一个activity组件:本程序activity和其他程序的activity. 若新的被激活的activity组件属于还有一个应用程序, ...
- 使用isql连接Sybase ASE数据库的常见错误及处理方式
使用isql连接Sybase ASE数据库 Sybase ASE客户端工具中有一个比较实用的命令行工具isql.利用isql可以对ASE数据库服务器进行几乎所有的管理维护工作. 下面用isql工具连接 ...
- 6个理由告诉你为什么要用NAS
当电脑硬盘容量满了,多数使用者第一个想法就是买一块几TB的硬盘来扩充,如果是笔电的使用者,第一个想到的是买一个外接式硬盘来备份资料,这样的想法并没有错,那是当你还不知道有「NAS」这个好用的东西,才会 ...