POJ - 3468 A Simple Problem with Integers(线段树区间更新,区间查询)
1、给出了一个序列,你需要处理如下两种询问。
"C a b c"表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000)。
"Q a b" 询问[a, b]区间中所有值的和。
2、线段树单点更新太费时,所以使用区间更新
3、
#include <cstdio> #define L(root) ((root) << 1)
#define R(root) (((root) << 1) + 1) const int MAXN = ;
int numbers[MAXN]; struct st
{
// 区间范围
int left, right;
// 更新值、区间总和
long long delta, sum;
} st[MAXN * ]; // 建树代码基本不变
void build(int root, int l, int r)
{
st[root].left = l, st[root].right = r, st[root].delta = ;
if (l == r)
{
st[root].sum = numbers[l];
return;
} int m = l + ((r - l) >> );
build(L(root), l, m);
build(R(root), m + , r);
st[root].sum = st[L(root)].sum + st[R(root)].sum;
} long long query(int root, int l, int r)
{
// 如查询区间恰等于节点区间,直接返回该区间总和即可
if (st[root].left == l && st[root].right == r)
{
return st[root].sum;
} // 否则需将当前区间的“缓冲”值更新下去并修正各节点区间的总和
if (st[root].delta)
{
st[L(root)].delta += st[root].delta;
st[R(root)].delta += st[root].delta;
st[L(root)].sum += st[root].delta * (st[L(root)].right - st[L(root)].left + );
st[R(root)].sum += st[root].delta * (st[R(root)].right - st[R(root)].left + );
st[root].delta = ;
} int m = st[root].left + ((st[root].right - st[root].left) >> );
if (r <= m)
{
return query(L(root), l, r);
}
else if (l > m)
{
return query(R(root), l, r);
}
else
{
return query(L(root), l, m) + query(R(root), m + , r);
}
} void update(int root, int l, int r, long long v)
{
// 如变更区间恰等于节点区间,只修正当前节点区间即可
if (st[root].left == l && st[root].right == r)
{
st[root].delta += v;
st[root].sum += v * (r - l + );
return;
} // 否则需向下修正相关节点区间
if (st[root].delta)
{
st[L(root)].delta += st[root].delta;
st[R(root)].delta += st[root].delta;
st[L(root)].sum += st[root].delta * (st[L(root)].right - st[L(root)].left + );
st[R(root)].sum += st[root].delta * (st[R(root)].right - st[R(root)].left + );
st[root].delta = ;
} int m = st[root].left + ((st[root].right - st[root].left) >> );
if (r <= m)
{
update(L(root), l, r, v);
}
else if (l > m)
{
update(R(root), l, r, v);
}
else
{
update(L(root), l, m, v);
update(R(root), m + , r, v);
}
// 同时一定要记得修正当前节点区间的总和
st[root].sum = st[L(root)].sum + st[R(root)].sum;
} int main()
{
int N, Q;
while (scanf("%d%d", &N, &Q) != EOF)
{
for (int i = ; i <= N; ++i)
{
scanf("%d", &numbers[i]);
} build(, , N); char cmd;
int l, r;
long long v;
while (Q--)
{
scanf(" %c", &cmd);
scanf("%d%d", &l, &r);
switch (cmd)
{
case 'Q':
printf("%lld\n", query(, l, r));
break; case 'C':
scanf("%lld", &v);
if (v)
{
update(, l, r, v);
}
break;
}
}
} return ;
}
POJ - 3468 A Simple Problem with Integers(线段树区间更新,区间查询)的更多相关文章
- poj 3468 A Simple Problem with Integers (线段树区间更新求和lazy思想)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 75541 ...
- (简单) POJ 3468 A Simple Problem with Integers , 线段树+区间更新。
Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...
- [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 线段树区间更新
id=3468">点击打开链接题目链接 A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072 ...
- POJ 3468 A Simple Problem with Integers(线段树,区间更新,区间求和)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 67511 ...
- POJ 3468 A Simple Problem with Integers(线段树区间更新)
题目地址:POJ 3468 打了个篮球回来果然神经有点冲动. . 无脑的狂交了8次WA..竟然是更新的时候把r-l写成了l-r... 这题就是区间更新裸题. 区间更新就是加一个lazy标记,延迟标记, ...
- POJ 3468 A Simple Problem with Integers(线段树区间更新,模板题,求区间和)
#include <iostream> #include <stdio.h> #include <string.h> #define lson rt<< ...
- POJ 3468 A Simple Problem with Integers 线段树 区间更新
#include<iostream> #include<string> #include<algorithm> #include<cstdlib> #i ...
- A Simple Problem with Integers 线段树 区间更新 区间查询
Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 115624 Accepted: 35897 Case Time Lim ...
- 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 ...
随机推荐
- JS获取粘贴内容
http://classjs.com/2013/03/05/js%E8%8E%B7%E5%8F%96%E7%B2%98%E8%B4%B4%E5%86%85%E5%AE%B9/ 思路:在编辑环境中,粘贴 ...
- 自动化项目配置或用例文件格式推荐--yaml
关于yaml YAML语言的设计目标,就是方便人类读写.如果你想要实现一些用ini不好做到的配置,可以使用yaml格式作为配置文件 大小写敏感 使用缩进表示层级关系 缩进时不允许使用Tab键,只允许使 ...
- 五、PL/SQL循环、游标、函数和过程
--PL/SQL基础知识学习 --一.PL/SQL语句块,基础语法格式 DECLARE --变量声明列表 info varchar(25); --变量声明 stu_unm integer := 15; ...
- java web 项目常用框架
java框架实在是太多了,网上一搜索一大箩筐,根本就了解不到什么. 我还是以我的经验来说一下j2ee的框架. 1.首先力推struts2框架,这是最经典的框架(可以说没有“之一”).可以帮你快速搭建出 ...
- 全局Session-GlobalSession
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.spri ...
- [NOIP1998] 提高组 洛谷P1013 进制位
题目描述 著名科学家卢斯为了检查学生对进位制的理解,他给出了如下的一张加法表,表中的字母代表数字. 例如: L K V E L L K V E K K V E KL V V E KL KK E E K ...
- 【ZJOI2017 Round1练习】D2T3 counter(线段树)
题意: 思路: 预处理出b[i]代表i位置之前比a[i]小的数的个数 以每个数为结尾的组数是线段树中(1,a[i]-1) 对于a[i]换到最后,相当于线段树中(a[i]+1,n)-- 交换后b[i]又 ...
- 牛客网 牛客网暑期ACM多校训练营(第三场)E KMP
链接:https://www.nowcoder.com/acm/contest/141/E 题目描述 Eddy likes to play with string which is a sequenc ...
- css中高度比img多出4px的问题
一句话概括:为什么<a>标签比里面的img高度多出4px 的问题,主要还是由于 img是inline element, it's height is caculated different ...
- Android中AsyncTask使用具体解释
在Android中我们能够通过Thread+Handler实现多线程通信.一种经典的使用场景是:在新线程中进行耗时操作.当任务完毕后通过Handler向主线程发送Message.这样主线程的Handl ...