【MX-X2-T6】「Cfz Round 4」Ad-hoc Master
【MX-X2-T6】「Cfz Round 4」Ad-hoc Master
所以什么时候才能有,对上脑电波的能力啊。
下文中,令根节点的深度为 \(0\)。
结论 \(1\):对于 \(1 \leq k < h\),所有 \(f_{u,k+1}\) 的异或和为深度为 \(k\) 的点权异或和
考虑证明,不妨对每个点 \(u\) 分别统计其产生的贡献:
-
若 \(d_u < k\),此时考虑在没有跨越根的路径上,其能衍生出的子节点个数是 \(2\) 的倍数,对于跨越根的路径也同样可以,故 \(w_u\) 产生的贡献为 \(0\)
-
若 \(d_u = k\),此时对于没有跨越根的路径同上,跨过根的路径部分长度为 \(1\),产生的子节点个数一定为 \(1\),故 \(w_u\) 产生的贡献为 \(w_u\)
-
若 \(d_u > k\),此时路径必然不会跨过根,可能为奇数的点只有最高点和次高点,而这两个点的贡献同样能够抵消,故 \(w_u\) 产生的贡献为 \(0\)
也就是说,我们将所有的 \(f_{u,k+1}\) 异或起来,就可以得到 \(f_{root,k}\)。
将得到的 \(f_{root,k}\) 和其他节点进行对比,找到相同的则令为根节点。
考虑如何找到根节点,我们求出所有点权值的异或和,再异或根节点的所有信息即可。
结论 \(2\):与点 \(u\) 距离为奇数的点,要么是所有奇数层的点,要么是所有偶数层的点
这是显然的,直接黑白染色,两点之间路径必然颜色交替。
我们考虑将所有点距离为奇数的点权值异或和求出,再与根节点的对应信息异或。
此时,我们要么得到 \(0\),这意味着该点可能与根节点同色,要么非 \(0\),必然与根节点异色。
倘若非 \(0\),黑点和白点的异或和为所有点权值的异或和。
倘若全为 \(0\),则由于必然有异色点,所有点的点权异或和为 \(0\)。
于是我们解决了这道题,复杂度 \(O(\sum 2^h h)\)。
//Ad astra per aspera
#include<iostream>
#include<cstdio>
using namespace std;
int f[100010][40],g[40];
void solve(){
int h;
scanf("%d",&h);
int n=(1<<h)-1,k=2*h-2;
for(int i=1;i<=k;i++){
g[i]=0;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=k;j++){
scanf("%d",&f[i][j]);
}
for(int j=1;j<h;j++){
g[j]^=f[i][j+1];
}
}
int root;
for(int i=1;i<=n;i++){
bool flag=true;
for(int j=1;j<=k;j++){
if(f[i][j]!=g[j]){
flag=false;
}
}
if(flag){
root=i;
}
}
int w_root=0;
for(int i=1;i<=n;i++){
int num=0;
for(int j=1;j<=k;j+=2){
num^=g[j];
num^=f[i][j];
}
w_root=max(w_root,num);
}
for(int i=1;i<h;i++){
w_root^=g[i];
}
printf("%d %d\n",root,w_root);
}
int main(){
int T;
scanf("%d",&T);
while(T--){
solve();
}
return 0;
}

浙公网安备 33010602011771号