题解:P6623 [省选联考 2020 A 卷] 树

Luogu

我们考虑计算 \(\bigoplus_{v\in son(u)}val(v)\) 来计算 \(val(u)\),那么就需要计算将 \(u\) 子树中所有点加 \(1\) 会导致哪些二进制位被取反。

当然我们可以使用 01-trie 整体加 \(1\),但这里还有一种神秘的做法。

发现给一个数加 \(1\) 相当于使最后一段连续的 \(1\) 消失,并将前面的 \(0\) 位取反。因此我们考虑对第 \(i\) 位,如果它会在加 \(1\) 时被取反,那么前 \(i-1\) 位必须都是 \(1\),就有 \(v\equiv 2^i-1\pmod {2^i}\)。由于我们要处理整个子树的信息,考虑开一个桶 \(cnt_{i,j}\) 表示前 \(i-1\) 位是 \(j\) 的数(即 \(v\equiv j\pmod{2^i}\)\(v\))的数量(当然由于我们求的是异或值,用 bool 存奇偶性即可)。

但是由于值在加 \(1\) 的过程中会发生变化,我们不能只存 \(v_i\),而是要与点的深度相关,存入 \(v_i+dep_i\),那么如果第 \(j\) 位会被取反,当且仅当(左侧减 \(1\) 是因为是否加 \(1\) 是根据 \(u\) 的儿子判断的):

\[v_i+dep_i-dep_u-1\equiv 2^j-1\pmod{2^j} \]

也就有:

\[v_i+dep_i\equiv dep_u\pmod{2^j} \]

所以我们只需通过 \(cnt_{j,dep_u\cap(2^j-1)}\) 来判断是否取反第 \(j\) 位就行了。

那么我们该如何维护这个桶呢?直接 dsu on tree 就行了,总时间复杂度为 \(O(n\log n\log V)\)

Code:

#include<iostream>
#include<vector>
#define rep(i,l,r) for(int i=(l);i<=(r);i++)
#define per(i,l,r) for(int i=(l);i>=(r);i--)
using namespace std;
const int maxn=525020,maxg=23;
bool kon[maxn<<1][maxg];
int av[maxn],ans[maxn],dep[maxn],siz[maxn],hson[maxn];
vector<int> G[maxn];
inline void getdep(int cur){
	siz[cur]=1;
	ans[cur]=av[cur];
	av[cur]+=dep[cur];
	for(int v:G[cur]){
		dep[v]=dep[cur]+1;
		getdep(v);
		siz[cur]+=siz[v];
		if(siz[v]>siz[hson[cur]])hson[cur]=v;
	}
}
inline void putin(int x){//入(出)桶,因为异或,两种操作是一样的。
	rep(v1,0,21)kon[av[x]&((1<<v1)-1)][v1]^=1;
	for(int v:G[x])putin(v);
}
inline void dfs(int cur,bool sv){
	for(int v:G[cur])if(v!=hson[cur]){
		dfs(v,false);
		ans[cur]^=ans[v];
	}
	if(hson[cur]){
		dfs(hson[cur],true);
		ans[cur]^=ans[hson[cur]];
	}
	for(int v:G[cur])if(v!=hson[cur])putin(v);
	rep(v1,0,21){//对每一位进行取反,求得 u 的答案
		ans[cur]^=kon[dep[cur]&((1<<v1)-1)][v1]<<v1;
	}
	rep(v1,0,21)kon[av[cur]&((1<<v1)-1)][v1]^=1;//加入根
	if(!sv)putin(cur);
}
typedef long long ll;
int main(){
	int in;
	cin>>in;
	rep(v1,1,in)scanf("%d",av+v1);
	rep(v1,2,in){
		int ip;
		scanf("%d",&ip);
		G[ip].push_back(v1);
	}
	getdep(1);
	dfs(1,true);
	ll oans=0;
	rep(v1,1,in){
		oans+=ans[v1];
	}
	cout<<oans<<endl;
	return 0;
}
posted @ 2025-07-21 18:51  FugiPig  阅读(12)  评论(0)    收藏  举报