题目一:http://poj.org/problem?id=3468

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 abc" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.

"Q ab" 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

The sums may exceed the range of 32-bit integers.

裸的区间更新,关于lazy标记,还是老话,在下一次更新或询问时才把区间信息传递(pushdown)下去。

代码:

#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define Max 100020
long long a,b,q,n;
long long sum[Max<<2],c,lazy[Max<<2];
void pushup(int rt)
{
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void pushdown(int rt,int m)
{
if(lazy[rt])
{
lazy[rt<<1] += lazy[rt];
lazy[rt<<1|1] += lazy[rt];
sum[rt<<1] += lazy[rt] * (m - (m>>1));
sum[rt<<1|1] += lazy[rt] * (m>>1);
lazy[rt] = 0;
}
}
void build(int l,int r,int rt)
{
sum[rt] = 0;
if(l == r)
{
scanf("%lld",&sum[rt]);
return;
}
int m = (r + l)>>1;
build(lson);
build(rson);
pushup(rt);
}
void Add(int L,int R,int v,int l,int r,int rt)
{
if(L <= l&&r <= R)
{
lazy[rt] += v;
sum[rt] += (long long)(r - l + 1) * v;
return ;
}
pushdown(rt,r-l+1);
int m = (r + l)>>1;
if(L <= m) Add(L,R,v,lson);
if(m < R) Add(L,R,v,rson);
pushup(rt);
}
long long query(int L,int R,int l,int r,int rt)
{
if(L <= l&&r <= R)
{
return sum[rt];
}
long long rec = 0;
int m = (r + l)>>1;
pushdown(rt,r-l+1);
if(L <= m) rec += query(L,R,lson);
if(m < R) rec += query(L,R,rson);
return rec;
}
int main()
{
scanf("%d%d",&n,&q);
build(1,n,1);
while(q--)
{
char qus[2];
scanf("%s",&qus);
if(qus[0] == 'C')
{
scanf("%d%d%d",&a,&b,&c);
Add(a,b,c,1,n,1);
}
else
{
scanf("%d%d",&a,&b);
printf("%lld\n",query(a,b,1,n,1));
} }
return 0;
}

题型二:http://acm.hdu.edu.cn/showproblem.php?pid=1698

把上题的求和改成更新区间值就可以了。

代码如下:

#include<iostream>
#include<cstdio>
#define Max 100010
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
int sum[Max<<2],lazy[Max<<2];
void pushup(int rt)
{
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void pushdown(int rt,int INL)
{
if(lazy[rt])
{
lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];
sum[rt<<1] = lazy[rt] * (INL - (INL>>1));
sum[rt<<1|1] = lazy[rt] * (INL>>1);
lazy[rt] = 0;
}
}
void build(int l,int r,int rt)
{
lazy[rt] = 0;
sum[rt] = 1;
if(r == l)
{
return;
}
int m = (r + l) >> 1;
build(lson);
build(rson);
pushup(rt);
}
void update(int L,int R,int val,int l,int r,int rt)
{
if(L <= l&&r <= R)
{
sum[rt] = val * (r-l+1);
lazy[rt] = val;
return;
}
pushdown(rt,r-l+1);
int m = (r + l)>>1;
if(L <= m) update(L,R,val,lson);
if(m < R) update(L,R,val,rson);
pushup(rt);
}
int main()
{
int T,n,x,y,z,q;
scanf("%d",&T);
int lala = T;
while(T--)
{
scanf("%d",&n);
build(1,n,1);
scanf("%d",&q);
while(q--)
{
scanf("%d%d%d",&x,&y,&z);
update(x,y,z,1,n,1);
}
printf("Case %d: The total value of the hook is %d.\n",(lala-T),sum[1]);
}
return 0;
}

【题型三-hdu-ColorTheBall】http://acm.hdu.edu.cn/showproblem.php?pid=1556

题意:把a,b区间的 气球都涂上颜色,输出每个气球被涂色的次数。

思路:每次更新只记录到所更新的区间便不再往下记录更新,不需要pushup,只需要在输出时pushdown更新一次到每个节点就可以了

经验教训: 不要用cout, 不要用cout, 不要用cout!

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 100010
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int lazy[maxn<<4];
int n;
//int index[maxn];
void build(int l, int r, int rt)
{
int m;
m = (l + r)>>1;
lazy[rt] = 0;
if(l == r) return;
build(lson);
build(rson);
} void pushdown(int rt)
{
if(lazy[rt])
{
lazy[rt<<1] += lazy[rt];
lazy[rt<<1|1] += lazy[rt];
lazy[rt] = 0;
}
} void paint(int l, int r, int rt, int L, int R)
{
if(L <= l && r <= R)
{
lazy[rt]++;
return ;
}
int m = (r+l)>>1;
if(L <= m) paint(lson, L,R);
if(m < R) paint(rson, L, R);
} void finalQuery(int l, int r, int rt)
{
int m = (l+r)>>1;
if(l == r)
{
printf("%d%c",lazy[rt],l==n?'\n':' ');
return;
}
pushdown(rt); //在查询的时候才pushdown
finalQuery(lson);
finalQuery(rson);
} int main()
{
while(scanf("%d", &n) != EOF&&n)
{
build(1,n,1);
for(int i = 0; i < n; i++)
{
int a, b;
scanf("%d%d", &a, &b);
paint(1, n, 1, a, b);
//cout<<"-"<<endl;
}
finalQuery(1, n, 1);
}
return 0;
}

ccnu-线段树-简单的区间更新(三题)的更多相关文章

  1. HDOJ--4893--Wow! Such Sequence!【线段树+单点、区间更新】

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4893 题意:给你一个长度n的数列,初始都为0.有三种操作,第一种给第k个位置的数加d.另外一种是查询区间 ...

  2. HDU4893【线段树单点、区间更新】

    题目链接[http://acm.hdu.edu.cn/showproblem.php?pid=4893] 题意:输入n.q.表示有n个数,初始化默认这n个数都为零,有q次操作,操作种类分为三种:1.输 ...

  3. codevs 1082 线段树练习 3 区间更新+延迟标记

    题目描述 Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述 Input Description 第一行一个正整数n,接下 ...

  4. codevs 1081 线段树练习 2 区间更新 单点查询 无lazy

    题目描述 Description 给你N个数,有两种操作 1:给区间[a,b]的所有数都增加X 2:询问第i个数是什么? 输入描述 Input Description 第一行一个正整数n,接下来n行n ...

  5. 洛谷 P3373:【模板】线段树 2(区间更新)

    题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含三个整数N.M.P,分别 ...

  6. HDU 3577Fast Arrangement(线段树模板之区间增减更新 区间求和查询)

    Fast Arrangement Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  7. POJ 3468 A Simple Problem with Integers(线段树模板之区间增减更新 区间求和查询)

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

  8. Codeforces295A - Greg and Array(线段树的成段更新)

    题目大意 给定一个序列a[1],a[2]--a[n] 接下来给出m种操作,每种操作是以下形式的: l r d 表示把区间[l,r]内的每一个数都加上一个值d 之后有k个操作,每个操作是以下形式的: x ...

  9. 线段树简单入门 (含普通线段树, zkw线段树, 主席树)

    线段树简单入门 递归版线段树 线段树的定义 线段树, 顾名思义, 就是每个节点表示一个区间. 线段树通常维护一些区间的值, 例如区间和. 比如, 上图 \([2, 5]\) 区间的和, 为以下区间的和 ...

随机推荐

  1. 判断js和css是否加载完成

    在通过ajax或者src动态获取js.css文件的时候,我们常常需要判断文件是否加载完成,以便进行进一步的操作,但是在检测js.css文件是否已经加载的策略上各浏览器并不统一,有很多坑,现在在这里总结 ...

  2. 【BZOJ】【2765】【JLOI2010】铁人双项比赛

    计算几何/半平面交 本来我是想去写POJ 1755的,然后想起了这道跟它很像的题,但应该是弱化版,所以就先写了这个…… 我们可以发现每个人的总用时,与k是呈一次函数关系的:$time_i=\frac{ ...

  3. Matlab求范数

    对 p = 2,这称为弗罗贝尼乌斯范数(Frobenius norm)或希尔伯特-施密特范数( Hilbert–Schmidt norm),不过后面这个术语通常只用于希尔伯特空间.这个范数可用不同的方 ...

  4. ASP.Net 上传进度条的实现方法

    对于加载时间比较长的ASP.NET页面,我们可以在客户端浏览器中显示进度条来显示页面正在装载.下面就是具体的实现过程: 新建项目,名字为WebPortal,在项目类型中选择Visual C#项目或者V ...

  5. 利用 random 与 tertools 模块解决概率问题

    Python 中的 random 与 tertools 模块可以得到伪随机数与排列.组合,下面利用这两个模块求解一些有趣的概率问题. 一.random 与 tertools 模块 random 模块常 ...

  6. 非阻塞式JavaScript脚本介绍

    JavaScript 倾向于阻塞浏览器某些处理过程,如HTTP 请求和界面刷新,这是开发者面临的最显著的性能问题.保持JavaScript文件短小,并限制HTTP请求的数量,只是创建反应迅速的网页应用 ...

  7. SWF Web播放器

    <HTML> <HEAD> <!-- saved from url=(0013)about:internet --> <TITLE> Untitled. ...

  8. Unity3D 批量图片资源导入设置

    原地址:http://blog.csdn.net/asd237241291/article/details/8433548 创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 QQ群:[] 本 ...

  9. 用 VIPER 构建 iOS 应用架构(1)

    [编者按]本篇文章由 Jeff Gilbert 和 Conrad Stoll 共同编写,通过构建一个基础示例应用,深入了解 VIPER,并从视图.交互器等多个部件理清 VIPER 的整体布局及思路.通 ...

  10. 最常用的javascript方法函数

    字符串长度截取 function cutstr(str, len) { var temp, icount = 0, patrn = /[^\x00-\xff]/, strre = "&quo ...