线段树模板【1】
单点增减,区间求和
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
struct Node { int l, r, mid, sum; }node[MAX]; void init(int a, int b, int n)//init(1,n+1,1); { node[n].l=a; node[n].r=b; node[n].mid=(a+b)/2; node[n].sum=0; if(a+1==b) return ; init(a, (a+b)/2; 2*n); init((a+b)/2, b, 2*n+1); } void add(int pos, int value, int n) // add(a,b,1); { node[n].sum+=value; if(node[n].l+1==node[n].r) return ; if(pos<node[n].mid) add(pos, value, 2*n); else add(pos, value, 2*n+1); } int sum(int a, int b, int n) //sum(a, b+1, 1); { if(node[n].l==a&&node[n].r==b) return node[n].sum; if(a<node[n].mid) { if(b<=node[n].mid) return sum(a, b, 2*n); else return sum(a, node[n].mid, 2*n)+sum(node[n].mid, b, 2*n+1); } else return sum(a, b, 2*n+1); }
单点替换,区间求和
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
struct Node { int l, r, mid, max; }node[MAXN]; void init(int a, int b, int n) { node[n].l=a; node[n].r=b; node[n].mid=(a+b)/2; node[n].max=-1; if(a+1==b) return ; init(a, (a+b)/2, 2*n); init((a+b)/2, b, 2*n+1); } void add(int pos, int value, int n) // 改变pos点值为value { if(value>node[n].max) node[n].max=value; if(node[n].l+1==node[n].r) return ; if(pos<node[n].mid) add(pos, value, 2*n); else add(pos, value, 2*n+1); } int maxnum(int a, int b, int n)//区间最大值 { if(node[n].l==a&&node[n].r==b) return node[n].max; if(a<node[n].mid) { if(b<=node[n].mid) { return maxnum(a,b,2*n); } else { return max(maxnum(a,node[n].mid,2*n),maxnum(node[n].mid,b,2*n+1)); } } else { return maxnum(a,b,2*n+1); } }