线段树区间修改与查询(求和)
来源:互联网 发布:java instance 编辑:程序博客网 时间:2024/05/29 16:53
P3372
#include<iostream> #include<cstdio>#include<algorithm>#include<cstring>#include<string>#define MAXN 200000#define LL long longusing namespace std;struct H{ LL addi,sum,l,r,len;}st[MAXN*4+5];LL a0[MAXN+5];void build(int o,int l,int r){ st[o].l=l,st[o].r=r,st[o].len=r-l+1; if(l==r) { st[o].sum=a0[l]; return; } else { int m=(l+r)>>1; build(o<<1,l,m); build((o<<1)|1,m+1,r); st[o].sum=st[o<<1].sum+st[(o<<1)|1].sum; }}void push(int o){ st[o<<1].addi+=st[o].addi; st[(o<<1)|1].addi+=st[o].addi; st[o<<1].sum+=st[o].addi*st[o<<1].len; st[(o<<1)|1].sum+=st[o].addi*st[(o<<1)|1].len;//push(o<<1),push((o<<1)|1);不用!下一层即可 st[o].addi=0;}void add(int o,int a,int b,int ad){ int l=st[o].l,r=st[o].r,len=st[o].len; int m=(l+r)>>1; if(l==a&&b==r) {st[o].sum+=len*ad,st[o].addi+=ad; return; } if(st[o].addi) push(o); if(b<=m) add(o<<1,a,b,ad); else if(a>m) add((o<<1)|1,a,b,ad); else//if(a<m&&b>m)× add(o<<1,a,m,ad),add((o<<1)|1,m+1,b,ad); st[o].sum=st[o<<1].sum+st[(o<<1)|1].sum;}LL ask(int o,int ql,int qr){ int l=st[o].l,r=st[o].r; if(ql>r||qr<l)return 0; if(ql<=l&&qr>=r)return st[o].sum; if(st[o].addi) push(o); int m=(l+r)>>1; if(qr<=m)return ask((o<<1),ql,qr); else if(ql>m)return ask((o<<1)|1,ql,qr); else return ask((o<<1),ql,m)+ask((o<<1)|1,m+1,qr);}int main(){ int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%lld",&a0[i]); build(1,1,n); for(int i=1;i<=m;i++) { int p,x,y,k; scanf("%d%d%d",&p,&x,&y); if(p==1) { scanf("%d",&k); add(1,x,y,k); } else { printf("%lld\n",ask(1,x,y)); } } return 0;}
前辈模板
#include<cstdio>using namespace std;struct tree{ long long addi,sum,l,r,len;}tr[800000];int n,q,d[200001];void build(int x,int l,int r){ tr[x].l=l,tr[x].r=r,tr[x].len=r-l+1; if(l==r){tr[x].sum=d[l];return ;} int m=(l+r)>>1; build(x<<1,l,m); build(x<<1|1,m+1,r); tr[x].sum=tr[x<<1].sum+tr[x<<1|1].sum;}void pushdown(int x){ tr[x<<1].addi+=tr[x].addi; tr[x<<1|1].addi+=tr[x].addi; tr[x<<1].sum+=tr[x].addi*tr[x<<1].len; tr[x<<1|1].sum+=tr[x].addi*tr[x<<1|1].len; tr[x].addi=0;}void add(int a,int b,int ad,int x){ int l=tr[x].l,r=tr[x].r,m=(tr[x].l+tr[x].r)>>1,len=tr[x].len; if(l==a&&r==b) { tr[x].addi+=ad; tr[x].sum+=len*ad; return ; } if(tr[x].addi) pushdown(x); if(b<=m) add(a,b,ad,x<<1); else if(a>m) add(a,b,ad,x<<1|1); else add(a,m,ad,x<<1),add(m+1,b,ad,x<<1|1); tr[x].sum=tr[x<<1].sum+tr[x<<1|1].sum;}long long ask(int a,int b,int x){ int l=tr[x].l,r=tr[x].r,m=(tr[x].l+tr[x].r)>>1; if(a==l&&b==r){return tr[x].sum;} if(tr[x].addi) pushdown(x); if(b<=m) return ask(a,b,x<<1); else if(a>m) return ask(a,b,x<<1|1); else return ask(a,m,x<<1)+ask(m+1,b,x<<1|1);}int main(){ int i,j,a,b,x; scanf("%d",&n); for(i=1;i<=n;++i) scanf("%d",&d[i]); build(1,1,n); scanf("%d",&q); for(i=1;i<=q;++i){ scanf("%d",&j); if(j==1){ scanf("%d%d%d",&a,&b,&x); add(a,b,x,1); } else { scanf("%d%d",&a,&b); printf("%ld\n",ask(a,b,1)); } } return 0;}
1 1
- 线段树区间修改与查询(求和)
- 【模板】线段树区间修改、区间求和、查询最值
- 【线段树】区间求和+区间修改(区间加)
- 线段树(区间修改,区间查询)
- 线段树 区间求和模板 (区间修改)
- 线段树(区间修改,区间求和)
- codevs1080 线段树(区间修改+区间求和
- 【线段树】区间求和(不带修改)
- 【线段树】区间求和+单点修改
- 线段树(单点修改,区间查询)
- 线段树(区间修改,单点查询)
- [线段树][区间修改&&查询]
- 线段树 (区间修改 区间查询 延迟标记)
- 线段树区间修改+区间查询
- [模板]-线段树-区间修改 + 区间查询
- hdoj1698Just a Hook【线段树区间修改+区间求和】
- 【模板】线段树_区间最值、区间求和、修改
- 线段树区间求和
- 什么是java 序列化,如何实现java 序列化?
- 2016秋招笔试面试题一:Java及基础部分
- 161230工作笔记之设计模式
- 面试题 HashMap 数据结构 实现原理
- 如何在代码中设置textView跑马灯效果(不是在xml中)
- 线段树区间修改与查询(求和)
- 39.4 Spring Boot Shiro权限管理【从零开始学Spring Boot】
- mysql 子查询总结
- 近期使用jQuery mobile做项目时遇到的问题小结
- 后台播放功能遭审核拒绝
- Bootstrap3 按钮-禁用状态
- 用MainActivity 实现 OnClickListener接口——点击按钮没有反应
- Flash Builder导入项目+web开发发布播放器
- Git记录