POJ 3468:A Simple Problem with Integers(线段树[成段更新])
题意:N个数Q次操作。一共两种操作:Q l r :询问[l,r]这个区间里的数字和,C l r c: [l,r]区间里的每个数都加上c。1 ≤ N,Q ≤ 100000.
方法:线段树的成段更新。注意懒惰标记。这只是为了有个模板。易错点在代码中以下划线标注。
//16:06
#include <cstdio>
#include <cstring>
#define N 100010
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 long long sum[N<<];
long long col[N<<];//一直WA,只因这里写成Int。这个和上面那个要同个类型才是。 void pushUp(int rt) {
sum[rt] = sum[rt<<] + sum[rt<<|];
} void pushDown(int len, int rt) {
if (col[rt]) {
col[rt<<] += col[rt];
col[rt<<|] += col[rt];
sum[rt<<] += (len-len/)*col[rt];
sum[rt<<|] += (len/)*col[rt];
col[rt] = ;
}
} void build(int l, int r, int rt) {
col[rt] = ;
if (l==r) {
scanf("%lld", &sum[rt]);
return;
}
int mid = (l+r)/;
build(lson);
build(rson);
pushUp(rt);
} void update(int L, int R, int v, int l, int r, int rt) {
if (L <= l && r <= R) {
col[rt] += v;
sum[rt] += (r-l+1ll)*v;
return;
}
pushDown(r-l+, rt);
int mid = (l+r)/;
if (L <= mid) update(L,R,v,lson);
if (R > mid) update(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];
}
pushDown(r-l+,rt);
int mid = (l+r)/;
long long ans = ;
if (L <= mid) ans += query(L,R,lson);
if (R > mid) ans += query(L,R,rson);
return ans;
} int main() {
int n, q;
while (scanf("%d%d", &n, &q) != EOF) {
build(,n,);
for (int i = ; i < q; i++) {
char com[];
scanf("%s", com);
if (com[] == 'Q') {
int l, r = ;
scanf("%d%d", &l, &r);
//printf("query %d %d\n", l, r);
printf("%lld\n", query(l,r,,n,));
} else if (com[] == 'C') {
int l, r, add;
scanf("%d%d%d", &l, &r, &add);
update(l,r,add,,n,);
}
}
}
return ;
}
另外感觉三个函数有很多重复点,写了一个紧凑版本,不过看起来代码量差不多,而且效率低了呢。
//16:06
#include <cstdio>
#include <cstring>
#define N 100010
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 long long sum[N<<];
long long col[N<<]; void pushUp(int rt) {
sum[rt] = sum[rt<<] + sum[rt<<|];
} void pushDown(int len, int rt) {
if (col[rt]) {
col[rt<<] += col[rt];
col[rt<<|] += col[rt];
sum[rt<<] += (len-len/)*col[rt];
sum[rt<<|] += (len/)*col[rt];
col[rt] = ;
}
} long long basicDo(bool isBuild, int L, int R, int v, int l, int r, int rt) {
if (isBuild) col[rt] = ;
if (l == r || L <= l && r <= R) {
if (isBuild) scanf("%lld", &sum[rt]);
col[rt] += v;
sum[rt] += (r-l+1ll)*v;
return sum[rt];
}
pushDown(r-l+, rt);
int mid = (l+r)/;
long long ans = ;
if (isBuild || L<= mid) ans += basicDo(isBuild,L,R,v,lson);
if (isBuild || R > mid) ans += basicDo(isBuild,L,R,v,rson);
pushUp(rt);
return ans;
}
void build(int l, int r, int rt) {
basicDo(true, ,,,l,r, rt);
}
void update(int L, int R, int v, int l, int r, int rt) {
basicDo(false, L, R, v, l, r, rt);
}
long long query(int L, int R, int l, int r ,int rt) {
return basicDo(false, L, R, , l, r, rt);
} int main() {
int n, q;
while (scanf("%d%d", &n, &q) != EOF) {
build(,n,);
for (int i = ; i < q; i++) {
char com[];
scanf("%s", com);
if (com[] == 'Q') {
int l, r = ;
scanf("%d%d", &l, &r);
//printf("query %d %d\n", l, r);
printf("%lld\n", query(l,r,,n,));
} else if (com[] == 'C') {
int l, r, add;
scanf("%d%d%d", &l, &r, &add);
update(l,r,add,,n,);
}
}
}
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 [题目类型]线段树 成段增减+区间求和 &题解: 线段树 ...
- 【POJ】3468 A Simple Problem with Integers ——线段树 成段更新 懒惰标记
A Simple Problem with Integers Time Limit:5000MS Memory Limit:131072K Case Time Limit:2000MS Descr ...
- POJ3468_A Simple Problem with Integers(线段树/成段更新)
解题报告 题意: 略 思路: 线段树成段更新,区间求和. #include <iostream> #include <cstring> #include <cstdio& ...
- 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 ...
- POJ 3468 A Simple Problem with Integers //线段树的成段更新
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 59046 ...
随机推荐
- day22-python之模块
1.os import os # print(os.getcwd()) # os.chdir("..") # print(os.getcwd()) # os.makedirs('d ...
- MongoDB之Replica Sets环境搭建
最近学习MongoDB,这两天在搭建复制集的时候碰到了不少问题,也踩了好多坑,现在在这里记录下来,以供自己和他人参考 (因为本人是初学者,所以遇到的问题也会比较初级,所以本文也比较适合初学者查阅) 背 ...
- freertos知识点笔记——队列、二值信号量、计数信号量
队列1.队列queue通常用于任务之间的通信,一个任务写缓存,另一个任务读缓存.队列还会有等待时间,2.阻塞超时时间.如果在发送时队列已满,这个时间即是任务处于阻塞态等待队列空间有效的最长等待时间.如 ...
- Tracer Deployment UVALive - 8271 二分图匹配
复习二分图又想起了这道题,裸的二分图匹配,直接匈牙利算法就可以了,mark一下这个比较好用的稠密图匈牙利算法模板 题目:题目链接 AC代码: #include <iostream> #in ...
- BFS、模拟:UVa1589/POJ4001/hdu4121-Xiangqi
Xiangqi Xiangqi is one of the most popular two-player board games in China. The game represents a ba ...
- SpringMVC之Controller简单使用
//环境 spring-4.3.18/JDK1.8/开发工具/IntelliJ IDEA 2018.2.5 x64 //工程结构图 //web.xml <?xml version="1 ...
- debian使用ibus
$ sudo apt-get install ibus ibus-pinyin 点击右上角的键盘图标,设置拼音输入法
- Linux学习-软件磁盘阵列 (Software RAID)
什么是 RAID 磁盘阵列全名是『 Redundant Arrays of Inexpensive Disks, RAID 』,英翻中的意思是:容错式廉价磁盘阵列.RAID 可以透过一个技术(软件或硬 ...
- HDU 2852 KiKi's K-Number 主席树
题意: 要求维护一个数据结构,支持下面三种操作: \(0 \, e\):插入一个值为\(e\)的元素 \(1 \, e\):删除一个值为\(e\)的元素 \(2 \, a \, k\):查询比\(a\ ...
- 光学字符识别OCR-3
连通性 可以看到,每一层的图像是由若干连通区域组成的,文字本身是由笔画较为密集组成的,因此往往文字也能够组成一个连通区域.这里的连通定义为 8邻接,即某个像素周围的8个像素都定义为邻接像素,邻接的像素 ...