Dfs序可以处理单点相加子树求和或者子树相加的问题,与线段树或bit结合即可。(也可以直接树剖)
注意点:若单点相加可以 din[x]=id,dout[x]=id,但是对于子树相加不能如此,会重复计算,要如下代码:
void dfs(int x,int fa){
din[x]=++id;
g[x]=id;//其实这行没用
for(int i=h[x];~i;i=ne[i]){
int j=e[i];
if(j==fa) continue;
dfs(j,x);
}
dout[x]=id;//这里不能加
}
对于exBIT(区间加区间和)
1.首先要差分,这样区间加方便了,那怎么求和呢?
2.可以注意差分数组做一遍前缀和=原数组,再前缀和就是和了
所以区间和等于两遍前缀和,画出图用补集思想可以发现变为了 (b1+b2+b3+……+bk)(k+1)-(1b1+2b2+3b3+…+bk*k)
代码如下:
int lowbit(int x){
return x&(-x);
}
void add(ll tr[],int x,ll c){
for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=c;
}
ll sum(ll tr[],int x){
ll res=0;
for(int i=x;i;i-=lowbit(i)) res+=tr[i];
return res;
}
ll query(int x){
return sum(tr1,x)*(x+1)-sum(tr2,x);
}
void modify(int x,int y,ll k){
add(tr1,x,k);add(tr1,y+1,-k);
add(tr2,x,k*x);add(tr2,y+1,-k*(y+1));//这里是-k*(y+1)而不是-k,别糊涂了
}