AT5140 [AGC035C] Skolem XOR Tree 题解

AT5140 [AGC035C] Skolem XOR Tree

给定一个正整数 \(N\)

试判断,是否存在这样一棵节点数为 \(2N\) 的树,满足:

  • \(∀i∈[1,n]\),第 \(i\) 号节点和第 \(i+n\) 号节点的权值均为 \(i\)

  • 第 \(i\) 号节点到第 \(i+N\) 号节点路径上的点的点权异或和恰为 \(i\)

sol

试考虑异或的性质 : $0 ⨁x=x $

也就是说,对于一对 \(i,n+i\) 要构造出,除了 \(i\) 以外一直到 \(n+i\) 的异或和为 \(0\) (包括 \(n+i\))

所以考虑 \(2n+1⨁2n=1\) 这个答案再异或上 \(1\)就是 \(0\) 了

所以我们可以讲 \(i\)和 \(i+1\) 看成一对来处理,一对 \(i,i+1,2n+i,2n+i+1\) 我们可以这样连

\(i+1--i --1--2n+i+1--2n+i\)

这样成对就可以满足了

然后考虑 \(1\) 怎么连,我们发现 \(1⨁2⨁3=0\),所以利用前面的性质

$1--2--3--n+1--n+2--n+3$6

如果 \(n\) 是偶数的话,上面的情况 \(n\)和 \(2n\) 是无法处理的

那么我们就要找一条经过 \(1\) 的路径 ,满足 \(x⨁y⨁1=n\) 那么将 \(n\) 连 \(x\) 连 \(1\) 连 \(y\) 连 \(2n\) 就满足了,但是注意不能选 \(3\) ,因为 \(3\) 不是和 \(1\) 直接相连的

通过观察样例我们发现,如果 \(n\) 是 \(2\) 的整数次幂无解,因为只有 \(n\) 的最高位是 \(1\) ,比 \(n\) 小的数不可能将最高位构造出 \(1\)

code

#include<bits/stdc++.h>
using namespace std;
int n,m;
int main(){
	freopen("AT5140.in","r",stdin);
	freopen("AT5140.out","w",stdout);
	scanf("%d",&n);m=log2(n);
	if(!((1<<m)^n))return printf("No\n"),0;
	printf("Yes\n");
	printf("%d %d\n",1,2);
    printf("%d %d\n",2,3);
    printf("%d %d\n",3,n+1);
    printf("%d %d\n",n+1,n+2);
    printf("%d %d\n",n+2,n+3);
    for(int i=2;2*i+1<=n;i++){
        printf("%d %d\n",1,2*i);
        printf("%d %d\n",1,2*i+1);
        printf("%d %d\n",2*i,2*i+n+1);
        printf("%d %d\n",2*i+1,2*i+n);
    }
    if(!(n&1)){
        for(int i=2;i<=n;i++){
            if(i==3)  continue;
            int y=(i^1^n);
            if(y==3||y>n)  continue;
            printf("%d %d\n",n,i);
            printf("%d %d\n",2*n,y);
            break;
        } 
    }
    return 0;
}
上一篇:【Python 1-18】Python手把手教程之——异常处理、try-except、error


下一篇:cf103202M. United in Stormwind