题意: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(线段树[成段更新])的更多相关文章

  1. POJ 3468 A Simple Problem with Integers (线段树成段更新)

    题目链接:http://poj.org/problem?id=3468 题意就是给你一组数据,成段累加,成段查询. 很久之前做的,复习了一下成段更新,就是在单点更新基础上多了一个懒惰标记变量.upda ...

  2. POJ 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)

    A Simple Problem with Integers [题目链接]A Simple Problem with Integers [题目类型]线段树 成段增减+区间求和 &题解: 线段树 ...

  3. 【POJ】3468 A Simple Problem with Integers ——线段树 成段更新 懒惰标记

    A Simple Problem with Integers Time Limit:5000MS   Memory Limit:131072K Case Time Limit:2000MS Descr ...

  4. POJ3468_A Simple Problem with Integers(线段树/成段更新)

    解题报告 题意: 略 思路: 线段树成段更新,区间求和. #include <iostream> #include <cstring> #include <cstdio& ...

  5. 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 ...

  6. 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 ...

  7. 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 ...

  8. [POJ] 3468 A Simple Problem with Integers [线段树区间更新求和]

    A Simple Problem with Integers   Description You have N integers, A1, A2, ... , AN. You need to deal ...

  9. poj 3468 A Simple Problem with Integers (线段树区间更新求和lazy思想)

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

  10. POJ 3468 A Simple Problem with Integers //线段树的成段更新

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

随机推荐

  1. 洛谷 P3328 【[SDOI2015]音质检测】

    这题我做的好麻烦啊... 一开始想分块来着,后来发现可以直接线段树 首先考虑一个性质,我们如果有数列的相邻两项f[i]和 f[i+1]那么用这两项向后推k项其线性表示系数一定(表示为f[i+k]=a∗ ...

  2. Golang Json测试

    结构体是谷歌搜索API package main import ( "encoding/json" "fmt" "io/ioutil" &q ...

  3. 03等待多个线程返回WaitForMultipleObject

    二. WaitForMultipleObject 等待单个线程返回 1. 函数原型 DWORD WINAPI WaitForMultipleObjects( _In_ DWORD nCount, _I ...

  4. 配置wamp开发环境之mysql的配置

    此前我已经将wamp配置的Apache.PHP.phpmyadmin全部配置完成,以上三种配置参照 配置wamp开发环境 下面我们来看看mysql的配置,这里用的是mysql5.5.20,下载地址: ...

  5. hessian应用示例

    因为公司的项目远程调用采用的是hessian,故抽时间了解了下hessian,自己也写了一个应用实例,以便加深对hessian的理解. Hessian是一个轻量级的remoting onhttp工具, ...

  6. sql执行过长,如何入手优化

    一条sql执行过长的时间,你如何优化,从哪些方面 1.查看sql是否涉及多表的联表或者子查询,如果有,看是否能进行业务拆分,相关字段冗余或者合并成临时表(业务和算法的优化)2.涉及链表的查询,是否能进 ...

  7. executing an update/delete query问题

    是因为在做SpringDataJpa更新和删除操作的时候Repository层没有加事务的注解,加上就行了: @Transactional @Query(value = "update ms ...

  8. hibernate源码分析1-保存一个对象

    要点 用了event的方式贯穿CRUD的过程 值得学习 用dynamic-insert 支持 插入时 可选 全字段插入 还是仅仅有值的字段插入. 返回主键的值 用了 Serializable 类型作为 ...

  9. python算法-排列组合

    排列组合 一.递归 1.自己调用自己 2.找到一个退出的条件 二.全排列:针对给定的一组数据,给出包含所有数据的排列的组合 1:1 1,2:[[1,2],[2,1]] 1,2,3:[[1,2,3],[ ...

  10. MacOS常用软件推荐

    1.效率提升神器Alfred 可以搜索文件.应用.web搜索.词典等等 链接:https://pan.baidu.com/s/1igv4tuXkuMFOPT9E6Cc5Jg 密码:3o51 软件解压密 ...