题意: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. MySQL中 IFNULL、NULLIF和ISNULL函数的用法

    mysql 中 ifnull().nullif().isnull()函数的用法讲解: 一.IFNULL(expr1,expr2)用法: 假如expr1不为NULL,则 IFNULL() 的返回值为ex ...

  2. 如何封装RESTful Web Service

    所谓Web Service是一个平台独立的,低耦合的,自包含的.可编程的Web应用程序,有了Web Service异构系统之间就可以通过XML或JSON来交换数据,这样就可以用于开发分布式的互操作的应 ...

  3. socketserver的使用

    socketserver底层也是使用线程实现的并发,直接上代码 # server import socketserver ''' socketserver使用模式: 1 功能类 class Myser ...

  4. 数字pid笔记(1)

    针对stm32中可以如下实现: p->IncrementVal = (p->Kp * (p->err - p->err_next)) + (p->Ki * p->e ...

  5. HDU:2255-奔小康赚大钱(KM算法模板)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2255 奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others) Mem ...

  6. Sublime插件开发——简单的代码模板插件

    最近一段一直使用sublime进行golang开发,整体感觉很不错,虽然比不上eclipse之类IDE强大,但是用起来很轻巧便捷,开发golang完全做够了.由于有一部分代码复用率很高,经常要用到,而 ...

  7. BZOJ 2243 染色 树链剖分

    题意: 给出一棵树,每个顶点上有个颜色\(c_i\). 有两种操作: C a b c 将\(a \to b\)的路径所有顶点上的颜色变为c Q a b 查询\(a \to b\)的路径上的颜色段数,连 ...

  8. SVN 删除所有目录下的“.svn”文件夹,让文件夹脱离SVN控制

    SVN 删除所有目录下的“.svn”文件夹,将如下语句拷备到记事本,并保存为 *.reg,双击导入注册表,在文件夹右键中就多了一条“Delete SVN Folders”,点击就可以删处此目录下的所有 ...

  9. tomcat6-servlet规范对接 与 ClassLoader隔离

    之前写的一个ppt 搬到博客来

  10. webdriver高级应用- 在ajax方式产生的浮动框中,单击选择包含某个关键字的选项

    Ajax简介: Ajax:局部刷新,原理上也是一个js,js调用服务器的远程接口刷新局部页面数据. Ajax = 异步 JavaScript 和 XML(标准通用标记语言的子集). Ajax 是一种用 ...