367 字
2 分钟
关于线段树
为防止老年痴呆,特地贴一份线段树的板子在此
尝有老登云”老年痴呆者,亦可传此线段树之模板咦!”自觉废物,故贴此详解,以防老年痴呆(悲)
完整代码
线段树~~~~
struct node{ int l,r; long long sum,lazy;}t[114514];更新线段树(将左右子节点的值传递到该节点)
void update(int i){ t[i].sum = t[i<<1].sum + t[i<<1|1].sum;}将lazy_tag传递下去
void pushdown(i){ if(t[i].lazy == 0) return; t[i<<1].lazy += t[i].lazy; t[i<<1|1].lazy += t[i].lazy; t[i<<1].sum += (t[i<<1].r - t[i<<1].l+1) * t[i].lazy;//一个区间数字数量×lazy_tag标记所增加的数=所需增加的数 t[i<<1|1].sum += (t[i<<1|1].r - t[i<<1|1].l+1) * t[i].lazy;//右区间同理 t[i].lazy = 0;//清理}如题,建树
void buildtree(int i,int l,int r)//传递区间范围,编号{ t[i].l = l; t[i].r = r; if(l==r) { t[i].sum = a[l]; return; }
int mid = (l+r)>>1; buildtree(i<<1,l,mid); buildtree(i<<1|1,mid+1,r); update(i);//跟新,将i号节点的左右子节点传递上来}区间修改
void change(int i,int l,int r,int x){ if(l<=t[i].l && t[i].r <= r) { t[i].sum += (t[i].r-t[i].l+1) * x; t[i].lazy += x; return; } if(t[i].l > r || t[i].r < l) return ; pushdown(i); //保证其子节点不会过期,保证后chagne的正确性 change(i<<1,l,r,x); change(i<<1|1,l,r,x); update(i);//更新}区间查询
int query(int i,int l,int r){ if(l<=t[i].l && t[i].r <= r)//当前区间完全被查询区间所包含 return t[i].sum;//直接返回 if(t[i].l > r || t[i].r < l) //完全没有交集的区间 return 0;//返回0 pushdown(i);//更新数据,保证正确性,防止过期 return query(i<<1,l,r) + query(i<<1|1,l,r); //返回左右子区间的和}