大意: 给定树, 每个点初始权值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;
}