1. 程式人生 > 其它 >AT5140 [AGC035C] Skolem XOR Tree 題解

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;
}