POJ3468 A Simple Problem with Integers
来源:互联网 发布:块语言编程游戏迷宫 编辑:程序博客网 时间:2024/06/13 12:18
一.原题链接: http://poj.org/problem?id=3468
二.题目大意:给出1到N个数,2种操作,Q a b查询从第a个数到第b个数的总和,C a b c从第a个数到第b个数每个数加上c。对于每次查询,输出总和。
三.思路:线段树成段更新模板题。所谓成段更新,就是加一个lazy标记,缓存要增加的元素,每次更新不更新到底,而是累积到lazy数组中,原题为add数组。要进行更深的查询或者更深的更新,用pushDown向下更新,这样就可以避免不必要的更新。
四.代码:
#include <cstdio>#include <cmath> using namespace std; const int MAX_N = 100100;const int INF = 0x3f3f3f3f; #define LC(t) t<<1#define RC(t) t<<1|1 struct node{ int l, r; int mid() { return l+r >> 1; }}seTree[4*MAX_N]; long long add[MAX_N<<2],sum[MAX_N<<2]; void build(int nd, int l, int r){ seTree[nd].l = l; seTree[nd].r = r; sum[nd] = add[nd] = 0; if(l == r) return; int mid = seTree[nd].mid(); build(LC(nd), l, mid); build(RC(nd), mid+1, r);} void pushDown(int nd, int len){ if(!add[nd]) return; add[LC(nd)] += add[nd]; add[RC(nd)] += add[nd]; sum[LC(nd)] += add[nd]*(len -(len>>1)); sum[RC(nd)] += add[nd]*(len>>1); add[nd] = 0;} void pushUp(int nd){ sum[nd] = sum[LC(nd)] + sum[RC(nd)];} void upDate(int nd, int l, int r,int ele){ if(l == seTree[nd].l && r ==seTree[nd].r){ sum[nd] += ele*(r-l+1); add[nd] += ele; return; } if(seTree[nd].l == seTree[nd].r) return; pushDown(nd, seTree[nd].r-seTree[nd].l+1); int mid = seTree[nd].mid(); if(r <= mid) upDate(LC(nd), l, r, ele); else if(l > mid) upDate(RC(nd), l, r, ele); else{ upDate(LC(nd), l, mid, ele); upDate(RC(nd), mid+1, r, ele); } pushUp(nd);} long long query(int nd, int l,int r){ if(seTree[nd].l == l &&seTree[nd].r == r) return sum[nd]; pushDown(nd, seTree[nd].r-seTree[nd].l+1); int mid = seTree[nd].mid(); if(r <= mid) return query(LC(nd), l, r); if(l > mid) return query(RC(nd), l, r); return query(LC(nd), l, mid) +query(RC(nd), mid+1, r);} int main(){ //freopen("in.txt","r", stdin); int N, Q, i, ele, a, b, c; char ch; while(~scanf("%d%d", &N,&Q)){ build(1, 1, N); for(i = 1; i <= N; i++){ scanf("%d", &ele); upDate(1, i, i, ele); } for(i = 1; i <= Q; i++){ scanf("\n%c %d %d",&ch, &a, &b); if(ch == 'C'){ scanf("%d", &c); upDate(1, a, b, c); } else printf("%I64d\n",query(1, a, b)); } } return 0;}
五. 易错点:本渣还是弄了好久,一开始混淆了线段树的左右边界和要查询和更新的左右边界,然后还犯了奇数整除会损失精度的错误,也就是说len-len/2与len/2是不一样的。
0 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
- yii 依赖注入
- 洛谷 P2777 [AHOI2016初中组]自行车比赛
- Android实践之ScrollView中滑动冲突处理
- Core Image人脸检测
- Java基础之(十七)继承和组合
- POJ3468 A Simple Problem with Integers
- 工作日志-Spinner的onItemSelected报空指针
- POJ 1797 Heavy Transportation【Dijkstra最短路变形】
- python提示ImportError: No module named win64com解决办法
- Java NIO框架Netty教程(一) – Hello Netty
- OpenGL Projection Matrix
- java 比较两个日期之间的大小
- iOS 怎样实现最多保留n位小数
- Java设计模式之原型模式与深浅拷贝