大意: 给定树, 每个点初始权值0, 每次询问给出$x$, $x$权值+1, 求距离$x$不超过2的权值和.
这题数据范围过大, 动态点分治卡不过去, 考虑其他做法
考虑每次只加范围$1$, c[0]是单点更新, c[1]是更新所有儿子
while (m--) { int x; scanf("%d", &x); ++c[fa[x]][0],++c[x][0]; ++c[x][1]; printf("%d ", c[x][0]+c[fa[x]][1]); }
改造一下就可以每次加范围$2$, c[2]是所有二级儿子.
while (m--) { int x; scanf("%d", &x); ++c[fa[fa[x]]][0],++c[fa[x]][0]; ++c[fa[x]][1],++c[x][1]; ++c[x][2]; printf("%d ", c[x][0]+c[fa[x]][1]+c[fa[fa[x]]][2]); }
很容易推广到$k$级更新
void update(int x, int k) { PER(i,1,k) ++c[x][i], ++c[x][i-1], x = fa[x]; ++c[x][0]; } int query(int x) { int ans = 0; REP(i,0,100) ans += c[x][i], x = fa[x]; return ans; }