线段树(大三的模板)
Up函数 用来更新父亲节点的值 void push(int w) { sum[w] = sum[2*w]+sum[2*w+1];//更新节点值 } 单点更新 先找出第p个数 然后更新他的值 void add(int p,int d,int l,int r,int w) { if(l==r) { sum[w]+=d; return ; } int m = (l+r)/2; if(p<=m) add(p,d,l,m,2*w); else add(p,d,m+1,r,2*w+1); push(w); } ****************************************** 区间求和 int query(int p1,int p2,int l,int r,int w) { if(p1<=l&&p2>=r)//区间被完全覆盖 return sum[w]; int m = (l+r)/2; int re = 0; if(p1<=m) re+=query(p1,p2,l,m,2*w); if(p2>m) re+=query(p1,p2,m+1,r,2*w+1); return re; } ***************************************88 区间更新 down 函数 void pushdown(int w,int m) { if(lz[w]) { lz[2*w]+=lz[w]; lz[2*w+1] += lz[w]; sum[2*w] += (lz[w]*(m-(m/2))); sum[2*w+1]+=(lz[w]*(m/2)); lz[w] = 0;//将延迟标记去除 } } void update(int a,int b,int da,int l,int r,int w) { if(a<=l&&b>=r) { lz[w] += da;//多次延迟标记 sum[w]+=da*(r-l+1); return ; } pushdown(w,r-l+1);//更新 int m = (l+r)/2; if(a<=m) add(a,b,da,l,m,2*w); if(b>m) add(a,b,da,m+1,r,2*w+1); pushup(w); }