线段树&树状数组
Posted lemon1234
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树&树状数组相关的知识,希望对你有一定的参考价值。
线段树:
lazy:记录当前区间更新的值,当需要继续查找时,才将lazy下传到左节点和右节点、
完整代码:
(结构体实现)
#include<iostream> #include<cstdio> #define maxn 100005 using namespace std; struct node{ int l,r,sum,lazy; }tree[maxn<<2]; void pushUp(int root){ tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum; } void pushDown(int root){ if(tree[root].lazy){ cout<<"AAA"<<endl; tree[root<<1].sum = (tree[root<<1].r - tree[root<<1].l +1)*tree[root].lazy; tree[root<<1|1].sum = (tree[root<<1|1].r - tree[root<<1|1].l +1)*tree[root].lazy; tree[root<<1].lazy += tree[root].lazy; tree[root<<1|1].lazy += tree[root].lazy; tree[root].lazy = 0; } } void buildTree(int root,int l,int r){ tree[root].l = l; tree[root].r = r; tree[root].lazy = 0; if(l==r){ scanf("%d",&tree[root].sum); return; } int mid = (l+r)>>1; buildTree(root<<1,l,mid); buildTree(root<<1|1,mid+1,r); pushUp(root); } void updatePoint(int root,int id,int v){ if(tree[root].l==id && tree[root].r==id){ tree[root].sum += v; cout<<"root="<<root<<" sum="<<tree[root].sum<<endl; return; } int mid = (tree[root].l + tree[root].r)>>1; if(id<=mid){ updatePoint(root<<1,id,v); }else{ updatePoint(root<<1|1,id,v); } pushUp(root); } void updateInterval(int root,int l,int r,int v){ if(tree[root].l==l && tree[root].r==r){ tree[root].sum += (tree[root].r-tree[root].l +1)*v; tree[root].lazy += v; return; } pushDown(root); int mid = (tree[root].l + tree[root].r)>>1; if(r<=mid){ updateInterval(root<<1,l,mid,v); }else if(l>=mid){ updateInterval(root<<1|1,mid+1,r,v); }else{ updateInterval(root<<1,l,mid,v); updateInterval(root<<1|1,mid+1,r,v); } pushUp(root); } int query(int root,int l,int r){ if(tree[root].l==l && tree[root].r==r){ return tree[root].sum; } pushDown(root); int mid = (tree[root].l + tree[root].r)>>1; if(r<=mid){ query(root<<1,l,r); }else if(l>=mid){ query(root<<1|1,l,r); }else{ return query(root<<1,l,mid) + query(root<<1|1,mid+1,r); } } int main() { int n,m; scanf("%d %d",&n,&m); buildTree(1,1,n); while(m--){ int op,l,r,v,id,ans; scanf("%d",&op); if(op==1){ scanf("%d %d",&id,&v); updatePoint(1,id,v); }else if(op==2){ scanf("%d %d %d",&l,&r,&v); updateInterval(1,l,r,v); }else{ scanf("%d %d",&l,&r); ans = query(1,l,r); printf("ans = %d",ans); } } return 0; }
以上是关于线段树&树状数组的主要内容,如果未能解决你的问题,请参考以下文章