牛客 72C 小H和游戏 (动态点分治)

大意: 给定树, 每个点初始权值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;
}
原文地址:https://www.cnblogs.com/uid001/p/10992840.html