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 ...
随机推荐
- Codevs1082 线段树练习 3
题目描述 Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述 Input Description 第一行一个正整数n,接下 ...
- k8s的Pod控制器
pod的配置清单常见选项: apiVersion,kind,metadata,spec,status(只读) spec: containers: nodeSelector: nodeName: res ...
- kubernetes安装rabbitmq集群
1.准备K8S环境 2.下载基础镜像,需要安装两种插件:autocluster.rabbitmq_management 方法一: 下载已有插件镜像 [root@localhost ~]#docker ...
- python并发编程之线程(创建线程,锁(死锁现象,递归锁),GIL锁)
什么是线程 进程:资源分配单位 线程:cpu执行单位(实体),每一个py文件中就是一个进程,一个进程中至少有一个线程 线程的两种创建方式: 一 from threading import Thread ...
- graph-bfs-八数码问题
这个看起来是童年回忆:) 大体思路是,将每个排列状态看成图中的一个点,状态之间转换说明有边.然后用bfs,如果遍历完之后还是没有找到目标状态, 则说明是无解的,否则输出步数.具体想法写在代码里吧,多多 ...
- spring事务(Transaction )报 marked as rollback-only异常的原因及解决方法
很多朋友在使用spring+hibernate或mybatis等框架时经常遇到报Transaction rolled back because it has been marked as rollba ...
- UVA - 11572 Unique Snowflakes 滑动扫描
题目:点击打开题目链接 思路:从左往右扫描,定义扫描左端点L,右端点R,保证每次往几何中添加的都是符合要求的连续的数列中的元素,L和R从0扫到n,复杂度为O(n),使用set维护子数列,set查找删除 ...
- python基础学习笔记——单继承
1.为什么要有类的继承性?(继承性的好处)继承性的好处:①减少了代码的冗余,提供了代码的复用性②提高了程序的扩展性 ③(类与类之间产生了联系)为多态的使用提供了前提2.类继承性的格式:单继承和多继承# ...
- 《小团团团队》第九次团队作业:Beta冲刺与验收准备
项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 实验十三 团队作业9:Beta冲刺与团队项目验收 团队名称 小团团团队 作业学习目标 (1)掌握软件黑盒测试技术:(2)学 ...
- java静态代理模式
代理模式分为动态代理和静态代理. 静态代理简述: 1.为其他对象提供一种代理,以控制对这个对象的访问. 2.代理对象会起到中介的作用,可以增加些功能,也可以去掉某些功能. 静态代理: 代理和被代理对象 ...