线段树中树链存储方式
回想建树方式:(从dfs_2开始)
void dfs_2(int x,int tt)
{
top[x]=tt;
po[x]=++cnt;
id[po[x]]=x;
if(son[x]!=0)dfs_2(son[x],pre); //这一步使重链成为连续区间;
for(int i=fst[x];i;i=use[x].next)
if(use[x].to!=fa[x]&&use[x].to!=son[x])
dfs_2(use[x].to,use[x].to);
}
我们用po[MAXN]:节点i在线段树中编号;
id[MAXN]:线段树中标号为i的节点对应树链中节点编号;、
(PS:建完树后pre[ ]数组便完成了任务)
void build(int k,int l,int r)
{
a[k].l=l;a[k].r=r;
if (l==r) {a[k].sum=a[k].max=data[pre[l]];return;}
int mid=(l+r)>>1;
build(k<<1,l,mid);build((k<<1)+1,mid+1,r);
up(x,l,r);
}
从dfs_2可看出: 重链的节点在线段树中是一段连续的区间的!
所以当点是重链上点时可以直接统计该点 x 到其 top[x] 间的数据;
若该点 x 为轻边中的点时,其 top[x] == x,只可以统计一个点;
并且这时只可以跳一下,用 fa[x] 跳到其父亲节点,继续判断;