写在zkw线段树前的话
- zkw线段树出处清华大学 张昆玮ppt《统计的力量》
链接:http://wenku.baidu.com/view/0c1bbba40029bd64783e2cca.html
- 写这篇博文的原因:好写!实用!
- 但有的题只能用回溯
- zkw线段树可以直接查看叶子结点
zkw线段树长什么样??(以长度为7为例)
把编号换做二进制看看
发现好多规律:
1. 左儿子是i<<1,右儿子是(i<<1)+1
2. 直接找到叶子(不用搜索)
3. …………
一:造树
首先开空间:
如何开空间?
1. 如果空间够直接开4倍
2. 不够就着大于区间长度的2^m*2(2^m>n)如果n=8,就开32
好了空间开完了,接下来就到植树造林的时间了
1. 叶子们
while(m<=n)m<<=1;
for(int i=m+1;i<=m+n;i++)
scanf("%d",&segtree[i]);
好了叶子就有值了
2. 父亲们
- 区间和
for(int i=m-1;i>=1;i--)
segtree[i]=segtree[i<<1]+segtree[(i<<1)+1];
- 区间最值
for(int i=m-1;i>=1;i--)
segtree[i]=max(segtree[i<<1],segtree[(i<<1)+1]);
或
for(int i=m-1;i>=1;i--)
segtree[i]=min(segtree[i<<1],segtree[(i<<1)+1]);
于是一棵zkw线段树就被我们用四行代码造好了
zkw线段树值呀!!
##二:单点查询与修改
1. 单点查询:直接找叶子
2. 单点修改:
scanf("%d%d",&x,&y);
segtree[x+m].sum=y;
for(int i=(x+m)>>1;i;i>>=1)
segtree[i].sum=segtree[i<<1].sum+segtree[(i<<1)^1].sum;
于是一棵zkw线段树就被我们用改好了
zkw线段树值呀!!