【模板】线段树 洛谷 3372 线段树
2017-01-13 19:08
344 查看
题目描述
如题,已知一个数列,你需要进行下面两种操作:1.将某区间每一个数加上x
2.求出某区间每一个数的和
分析
简单的线段树+lazy标记复习一下如何写lazy。
code
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<string> #include<algorithm> using namespace std; struct arr{ int x,y; long long lazy; long long sum; }f[3000000]; int n,m; void delay(int x)//延迟标记。 { f[x*2].lazy+=f[x].lazy; f[x*2+1].lazy+=f[x].lazy; f[x*2].sum+=(f[x*2].y-f[x*2].x+1)*f[x].lazy; f[x*2+1].sum+=(f[x*2+1].y-f[x*2+1].x+1)*f[x].lazy; f[x].lazy=0; } int insert(int r,int x,int y,int add)//线段树修改操作。 { delay(r); f[r].sum+=(y-x+1)*add; if ((f[r].x==x)&&(f[r].y==y)) { f[r].lazy+=add; return 0; } int mid=(f[r].x+f[r].y)/2; if (y<=mid) insert(r*2,x,y,add); else if (x>mid) insert(r*2+1,x,y,add); else insert(r*2,x,mid,add),insert(r*2+1,mid+1,y,add); } long long find(int r,int x,int y)//线段树查找。 { delay(r); if ((f[r].x==x)&&(f[r].y==y)) return f[r].sum; int mid=(f[r].x+f[r].y)/2; if (y<=mid) return find(r*2,x,y); else if (x>mid) return find(r*2+1,x,y); else return find(r*2,x,mid)+find(r*2+1,mid+1,y); } int maketree(int r,int x,int y)//建树 { f[r].x=x; f[r].y=y; f[r].lazy=0; f[r].sum=0; if (x==y) return 0; int mid=(x+y)/2; maketree(r*2,x,mid),maketree(r*2+1,mid+1,y); } int main() { scanf("%d%d",&n,&m); maketree(1,1,n); for (int i=1;i<=n;i++) { int x; scanf("%d",&x); insert(1,i,i,x); } for (int i=1;i<=m;i++) { int l,x,y,w; scanf("%d",&l); if (l==1) { scanf("%d%d%d",&x,&y,&w); insert(1,x,y,w); } else { scanf("%d%d",&x,&y); printf("%lld\n",find(1,x,y)); } } return 0; }
相关文章推荐
- 洛谷3372[模板]线段树1
- 洛谷 3372_【模板】线段树 1_线段树
- 【Splay】洛谷3372 【模板】线段树 1
- 洛谷 P3372 线段树模板
- 【洛谷3834】 【模板】可持久化线段树 (主席树)
- 洛谷 P3372 线段树【模板1】
- 洛谷 3380 【模板】二逼平衡树(树状数组套权值线段树)
- 洛谷.3834.[模板]可持久化线段树(主席树 静态区间第k小)
- P3372 【模板】线段树 1 洛谷
- [洛谷3373]【模板】线段树 2
- 洛谷P3373 [ 模板] 线段树 (乘法和加法)
- 洛谷 P3373 【模板】线段树 2
- 洛谷P3380 【模板】二逼平衡树(树套树,树状数组,线段树)
- 【洛谷1592】【模板】template 线段树 线段树裸题
- AC日记——【模板】线段树 1 洛谷 P3372
- 洛谷1908 逆序对 权值线段树模板
- 洛谷3372 线段树1
- 洛谷1531 线段树模板:区间最值
- 洛谷 P3372 【模板】线段树 1
- 洛谷 P3372 【模板】线段树 1