线段树求和
来源:互联网 发布:阿里云汽车荣威rx5 编辑:程序博客网 时间:2024/05/22 11:46
依旧是单纯地存个板。
指针实现。
区间修改区间查询
#include<cstdio>#include<cstring>#include<iostream>#define ll long longusing namespace std;const int N = 400010;int n,m;int a[N];struct node{ ll sum,flag; node *ls,*rs; void update(){ sum=ls->sum+rs->sum; } void pushdown(int l,int r){ if(flag){ int mid=(l+r)>>1; ls->sum+=(long long)(mid-l+1)*flag; ls->flag+=flag; rs->sum+=(long long)(r-mid)*flag; rs->flag+=flag; flag=0; } }}pool[N],*tail=pool,*root;node *build(int l,int r){ node *bt=++tail; if(l==r){ bt->sum=a[l]; bt->flag=0; } else{ int mid=(l+r)>>1; bt->ls=build(l,mid); bt->rs=build(mid+1,r); bt->update(); bt->flag=0; } return bt;}void modify(node *bt,int l,int r,int pos,int val,int delta){ if(pos<=l&&val>=r){ bt->sum+=(long long)(r-l+1)*delta; bt->flag+=delta; return ; } int mid=(l+r)>>1; bt->pushdown(l,r); if(pos<=mid) modify(bt->ls,l,mid,pos,val,delta); if(val>mid) modify(bt->rs,mid+1,r,pos,val,delta); bt->update();} ll query(node *bt,int l,int r,int pos,int val){ if(pos<=l&&val>=r) return bt->sum; int mid=l+r>>1; bt->pushdown(l,r); ll ans=0; if(pos<=mid) ans+=query(bt->ls,l,mid,pos,val); if(val>mid) ans+=query(bt->rs,mid+1,r,pos,val); return ans;}int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); root=build(1,n); scanf("%d",&m); for(int i=1;i<=m;i++){ int d; scanf("%d",&d); if(d==1){ int l,r,delta; scanf("%d%d%d",&l,&r,&delta); modify(root,1,n,l,r,delta); } if(d==2){ int l,r; scanf("%d%d",&l,&r); printf("%lld\n",query(root,1,n,l,r)); } } return 0;}
数组
#include<cstdio>#include<cstring>#define ll long longusing namespace std;const int N = 4000010;int n,m;int a[N];struct node{ ll sum,flag; int l,r; }tree[N];void pushdown(int root){ int flag=tree[root].flag; int l=tree[root].l,r=tree[root].r; if(flag){ int mid=(l+r)>>1; tree[root<<1].flag+=flag; tree[root<<1|1].flag+=flag; tree[root<<1|1].sum+=(long long)(r-mid)*flag; tree[root<<1].sum+=(long long)(mid-l+1)*flag; tree[root].flag=0; }}void build(int root,int l,int r){ tree[root].l=l,tree[root].r=r; if(l==r){ tree[root].sum=a[l]; tree[root].flag=0; } else{ int mid=(l+r)>>1; build(root<<1,l,mid); build(root<<1|1,mid+1,r); tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum; tree[root].flag=0; }}void modify(int root,int pos,int val,int delta){ int l=tree[root].l,r=tree[root].r; if(l>=pos&&r<=val){ tree[root].sum+=(long long)(r-l+1)*delta; tree[root].flag+=delta; return ; } int mid=(l+r)>>1; pushdown(root); if(pos<=mid) modify(root<<1,pos,val,delta); if(val>mid) modify(root<<1|1,pos,val,delta); tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;}ll query(int root,int pos,int val){ int l=tree[root].l,r=tree[root].r; if(l>=pos&&r<=val) return tree[root].sum; ll ans=0; pushdown(root); int mid=(l+r)>>1; if(pos<=mid) ans+=query(root<<1,pos,val); if(val>mid) ans+=query(root<<1|1,pos,val); return ans;}int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); build(1,1,n); scanf("%d",&m); for(int i=1;i<=m;i++){ int d; scanf("%d",&d); if(d==1){ int l,r,delta; scanf("%d%d%d",&l,&r,&delta); modify(1,l,r,delta); } if(d==2){ int l,r; scanf("%d%d",&l,&r); printf("%lld\n",query(1,l,r)); } } return 0;}
阅读全文
0 0
- hdu1394~线段树求和
- 线段树区间求和
- 线段树求和,最大公约数
- 【BJTU+求和+线段树】
- 线段树求和
- poj3468(线段树区间求和)
- poj3468 线段树区间求和
- hdu1166线段树模板求和
- 线段树区间更新+求和
- 线段树单点更新+求和
- HDU 1166(线段树,区间求和)
- poj 3468(线段树应用:区间求和)
- hdu3874/hdu3333 线段树区间求和
- hdu1698(线段树染色区间求和)
- HDU1698(线段树区间更新求和)
- 线段树(区间更新求和)
- 线段树之单点更新,区域求和
- 线段树之单点更新求和hdoj1166
- 2017.7.12 确定了方向,大数据。
- 8步助你开源硬件起步!
- SQL 语句(二)--------------数据查询(简单查询)
- Codeforces #803E: Roma and Pokers 题解
- Struts2中访问Servlet中的API(ActionContext,ServletActionContext)两种方式
- 线段树求和
- 《GPU高性能编程 CUDA实战》(CUDA By Example)读书笔记
- 友元函数
- qml与c++的简单实例,Connections信号连接
- python爬虫
- JVM内存泄露与内存溢出的区别
- c++字符串读入写入小结
- SQL 语句(三)--------------数据查询(连接查询)
- 猪和回文