POJ3468 A Simple Problem with Integers
来源:互联网 发布:linux 文件夹实时同步 编辑:程序博客网 时间:2024/06/05 19:38
题目大意:线段树区间加减,区间求和。
时间限制:5000ms
进行了位运算和输入优化,用时1469ms
分析:
build函数是建树,边界时把数据输到add数组里,add数组也就是常说的lazy标记,再把add的值赋给sum,建树完毕。
用sum[o]表示“如果只执行结点o及其子孙结点中的add操作,结点o对应区间中的所有数之和”,这样可以方便维护。
在执行update操作时,递归访问到的结点全部都要维护,并且是在递归返回后维护,因为这样子树的sum已经更新。
查询操作多加一个参数,表示当前区间的所有祖先结点add值之和,用全局变量sumv表示答案。
接下来是一些位运算优化,自行看代码。
数组开2.5倍区间长度会爆,开3倍不会。
数据类型用long long.
#include <iostream>#include <cstdio>using namespace std;typedef long long LL;char c;int n, q, x, y, z;LL sumv, sum[300005], add[300005];void build(int o, int L, int R) {if(L == R) {scanf("%lld", &add[o]);sum[o] = add[o];return;}int m = (L+R) >> 1;build(o<<1, L, m);build(o<<1 | 1, m+1, R);sum[o] = sum[o<<1] + sum[o<<1 | 1];}void maintain(int o, int L, int R) {sum[o] = 0;if(R > L) sum[o] = sum[o<<1] + sum[o<<1 | 1];sum[o] += add[o] * (R-L+1);}void update(int o, int L, int R) {if(x <= L && y >= R)add[o] += z;else {int m = (L+R) >> 1;if(x <= m) update(o<<1, L, m);if(y > m) update(o<<1 | 1, m+1, R);}maintain(o, L, R);}void query(int o, int L, int R, LL addv) {if(x <= L && y >= R)sumv += sum[o] + addv * (R-L+1);else {int m = (L+R) >> 1;if(x <= m) query(o<<1, L, m, addv+add[o]);if(y > m) query(o<<1 | 1, m+1, R, addv+add[o]);}}int main() {scanf("%d%d", &n, &q);build(1, 1, n);while(q--) {cin>>c;if(c == 'Q') {scanf("%d%d", &x, &y);sumv = 0;query(1, 1, n, 0);printf("%lld\n", sumv);}else {scanf("%d%d%d", &x, &y, &z);update(1, 1, n);}}return 0;}
3 0
- poj3468 A Simple Problem with Integers
- POJ3468:A Simple Problem with Integers
- poj3468 A Simple Problem with Integers
- poj3468 A Simple Problem with Integers
- POJ3468-A Simple Problem with Integers
- POJ3468--A Simple Problem with Integers
- POJ3468 A Simple Problem with Integers
- [POJ3468]A Simple Problem with Integers
- POJ3468 A Simple Problem with Integers
- POJ3468 A Simple Problem with Integers
- POJ3468 A Simple Problem with Integers
- poj3468 A Simple Problem with Integers
- POJ3468 A Simple Problem with Integers
- poj3468 A Simple Problem with Integers
- poj3468 A Simple Problem with Integers
- poj3468 A Simple Problem with Integers
- poj3468 A Simple Problem with Integers
- poj3468 A Simple Problem with Integers
- VOIP学习笔记
- ps学习笔记
- 蓝桥杯 历届试题 7对数字 直角三角形
- LeetCode 之 Permutations
- 适配器模式
- POJ3468 A Simple Problem with Integers
- 2016网易研发工程师
- 数列转换
- 蛇形填数
- PythonChallenge Mission 8
- iOS开发ARC内存管理技术要点
- 排序算法nth_element()和partition()
- Android Studio学习之签名打包APK
- 学习设计模式-大力推荐伟帅写的设计模式导学目录