Poj 3468 A Simple Problem with Integers - 线段树
来源:互联网 发布:外国人眼中的丑女知乎 编辑:程序博客网 时间:2024/06/06 06:52
题目大意:给定一组数据,然后对应两个操作
Q a b 查询[a,b]的和
C a b c 将[a,b]的数字都加上c
题目分析:赤裸裸的区间求和和区间修改,可以用树状数组做的,但是这里是练习线段树。所以用线段树做。
每次要修改[a,b],不需要直接修改到叶子结点。如果恰好当前区间是想要修改的区间,那么其子结点就不用修改了。这里这样是为了优化update操作。所以当query该区间的子区间时,需要更新修改的值。
画个图吧。。。
例如当更新区间为[1,10]的时候,直接标记该结点的该变量为c,不用修改下面的结点。
当修改[4,6]的时候,就要一直修改下去....
但是,在查询时需要实时更新每个结点的该变量。比如只更新了[1,10],但是如果要查询[4,6]的话,压根没有改变。所以在查询操作的时候要更新改变量。
如果[1,10]有改变,那么该区间的子区间也全部被修改过。
下面是代码:
#include <stdio.h>#include <algorithm>using namespace std;#define maxn 100100struct Node{ int l; int r; long long sum; long long lnc;} node[maxn*5];int num[maxn];void push_up(int rt){ node[rt].sum = node[rt<<1].sum + node[rt<<1|1].sum;}void build(int l,int r,int rt){ node[rt].l = l; node[rt].r = r; node[rt].lnc = 0; if(l == r) { node[rt].sum = num[l]; return ; } int mid = (l + r) >> 1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); push_up(rt); }void update(int rt,int L,int R,int add){ node[rt].sum += (R-L+1) * add; int l = node[rt].l; int r = node[rt].r; if(l == L && r == R) { node[rt].lnc += add; return ; } int mid = (l + r ) >> 1; if(L > mid) update(rt<<1|1,L,R,add); else if(R <= mid) update(rt<<1,L,R,add); else { update(rt<<1,L,mid,add); update(rt<<1|1,mid+1,R,add); }}long long query(int rt,int L,int R,long long add){ int l = node[rt].l; int r = node[rt].r; if(l == L && r == R) return node[rt].sum + (R-L+1) * add; add += node[rt].lnc; int mid = (l + r) >> 1; if(L > mid) return query(rt<<1|1,L,R,add); else if(R <= mid) return query(rt<<1,L,R,add); else return query(rt<<1,L,mid,add) + query(rt<<1|1,mid+1,R,add);}int main(){ int N,Q; //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); scanf("%d%d",&N,&Q); { for(int i = 1; i <= N; i++) scanf("%d",&num[i]); build(1,N,1); for(int i = 1; i <= Q; i++) { char s[2]; scanf("%s",s); if(s[0] == 'Q') { int l,r; scanf("%d%d",&l,&r); printf("%lld\n",query(1,l,r,0)); } else { int l,r,add; scanf("%d%d%d",&l,&r,&add); if(add == 0) continue; update(1,l,r,add); } } } return 0;}
- POJ 3468 A Simple Problem with Integers(线段树)
- POJ 3468 A Simple Problem with Integers (线段树)
- POJ 3468 A SIMPLE PROBLEM WITH INTEGERS(线段树)
- poj 3468 A Simple Problem with Integers 基础线段树
- POJ 3468 A Simple Problem with Integers 线段树
- POJ 3468 A Simple Problem with Integers【线段树】
- 【线段树】北大 poj 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers 线段树!!!!
- poj 3468 A Simple Problem with Integers【线段树】
- poj 3468 A Simple Problem with Integers(线段树)
- POJ 3468 A Simple Problem with Integers 线段树
- poj 3468 A Simple Problem with Integers[线段树 ]
- POJ 3468 A Simple Problem with Integers 线段树
- poj 3468 A Simple Problem with Integers(线段树区区)
- 线段树 POJ 3468 A Simple Problem with Integers
- POJ 3468 A Simple Problem with Integers----线段树
- POJ 3468 A Simple Problem with Integers(线段树)
- poj-3468-A Simple Problem with Integers(线段树)
- Windows命令大全(转)
- getRequestDispatcher()与sendRedirect()的区别
- swing低级应用之tree
- \r与\n
- performSelector:withObject:afterDelay: 精要概览(持续更新)
- Poj 3468 A Simple Problem with Integers - 线段树
- Java垃圾回收策略
- 交叉编译bash 4.2
- java 小技巧
- Android Wifi
- ACM暑期集训总结与感想
- Office 365-SharePoint2013 Online
- Java操作Excel文件以及在Android中的应用
- HDU 4454 Stealing a Cake (计算几何+三分)