poj 3468 线段树+懒标记
2015-08-02 19:29
267 查看
简单的线段树区间求和问题,每次改变区间值得时候采用懒标记的操作,等到下次经过这个区间的时候再将懒标记向下传递。
#include <cstdio> #include <iostream> using namespace std; int n,q; int a[100005]; long long sum[500005],lazy[500005]; void build(int l,int r,int k) { lazy[k]==0; if (l==r) { sum[k]=a[l]; return; } int mid=(l+r)>>1; build(l,mid,2*k); build(mid+1,r,2*k+1); sum[k]=sum[2*k]+sum[2*k+1]; } void pushdown(int m,int k) { if (lazy[k]) { lazy[2*k]+=lazy[k]; lazy[2*k+1]+=lazy[k]; sum[2*k]+=(long long)lazy[k]*(m-(m>>1)); sum[2*k+1]+=(long long)lazy[k]*(m>>1); lazy[k]=0; } } long long work(int l,int r,int k,int L,int R) { if ((L<=l)&&(r<=R)) { return sum[k]; } pushdown(r-l+1,k); int mid=(l+r)>>1; if (R<=mid) return work(l,mid,2*k,L,R); else if (L>mid) return work(mid+1,r,2*k+1,L,R); else return work(l,mid,2*k,L,mid)+work(mid+1,r,2*k+1,mid+1,R); } void change(int l,int r,int k,int L,int R,int VAL) { if ((L<=l)&&(r<=R)) { lazy[k]+=VAL; sum[k]+=(long long)VAL*(R-L+1); return; } pushdown(r-l+1,k); int mid=(l+r)>>1; if (R<=mid) change(l,mid,2*k,L,R,VAL); else if(L>mid) change(mid+1,r,2*k+1,L,R,VAL); else { change(l,mid,2*k,L,mid,VAL); change(mid+1,r,2*k+1,mid+1,R,VAL); } sum[k]=sum[2*k]+sum[2*k+1]; } int main() { scanf("%d%d",&n,&q); for (int i=0;i<n;i++) scanf("%d",&a[i]); build(0,n-1,1); for (int i=0;i<q;i++) { char ch[5]; int a,b,c; scanf("%s%d%d",ch,&a,&b); a--; b--; if (ch[0]=='Q') { printf("%I64d\n",work(0,n-1,1,a,b)); } else { scanf("%d",&c); change(0,n-1,1,a,b,c); } } }
相关文章推荐
- Android实例-路径信息及文件和文件夹的操作(XE8+小米2)
- GitHub 的简单使用
- 煎饼侠
- 乘法逆元的作用
- Being a Good Boy in Spring Festival HDOJ (尼姆博弈)
- Implement Trie (Prefix Tree) -- leetcode
- 字串的循环旋转
- Box2D C++教程 第三节:Testbed结构
- 【HDOJ 2147】 kiki's game
- UVALive 6661 解题心得
- Reverse反转算法+斐波那契数列递归+Reverse反转单链表算法--C++实现
- L-BFGS算法(有限内存BFGS算法)
- Java虚拟机参数设置
- Linux中rmdir和rm
- 双向链表的实现---数据结构学习(三)
- 黑马程序员---iOS基础---Foundation框架
- 企业文化
- POJ2456 Aggressive cows(对整数二分)
- HDU 5224 解题心得
- CodeForces 556A 解题心得