zoukankan      html  css  js  c++  java
  • 【AGC035C】Skolem XOR Tree

    题目

    题目链接:https://atcoder.jp/contests/agc035/tasks/agc035_c

    • 给定一个正整数 (N)
    • 试判断,是否存在这样一棵节点数为 (2N) 的树,满足:
      • (forall i in [1,n]),第 (i) 号节点和第 (i+n) 号节点的权值均为 (i)
      • (i) 号节点到第 (i+N) 号节点路径上的点的点权异或和恰为 (i)
    • 若不存在这样的树,请输出一行 No
    • 否则先输出一行 Yes,然后再输出 (2N-1) 行,每行两个正整数 (u,v) 描述树上的一条连接 (u,v) 的边。
    • (1 leq N leq 10^5)

    思路

    对于一个偶数 (x),有 (x ext{ xor }(x+1)=1)。考虑连边 ((1,x),(1,x+1),(x,x+1+n),(x+1,x+n))。这样从 (x)(x+n) 的路径,以及从 (x+1)(x+1+n) 的路径,都是符合要求的。
    然后考虑点 (1) 应该如何匹配。观察到 (1 ext{ xor }2 ext{ xor }3=0),所以可以连边 ((1,2),(2,3),(3,1+n),(1+n,2+n),(2+n,3+n))
    然后当 (n) 是偶数时,无法像刚刚那样利用 (n+1) 来进行匹配。那么:

    • 如果 (n=2^k),那么除了 (n)(2n) 以外,所有数在二进制下第 (k) 位都为 (0),那么一定无解。
    • 如果 (n eq 2^k),只需要找到一组 (x,y),满足 (x ext{ xor } y ext{ xor }1=n),然后连边 ((x,n),(y,2n)) 即可。注意 (x)(y) 都不能为 (3) 且必须小于 (n)。容易发现是一定存在这样的 (x,y) 的。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    int n;
    
    int main()
    {
    	scanf("%d",&n);
    	for (int i=0;i<=18;i++)
    		if (n==(1<<i)) return printf("No"),0;
    	printf("Yes
    1 2
    2 3
    3 %d
    %d %d
    %d %d
    ",n+1,n+1,n+2,n+2,n+3);
    	for (int i=4;i<n;i+=2)
    		printf("1 %d
    1 %d
    %d %d
    %d %d
    ",i,i+1,i,i+1+n,i+1,i+n);
    	if (!(n&1))
    		for (int i=2;i<n;i++)
    			if (i!=3 && (n^1^i)!=3 && (n^1^i)<n)
    				return printf("%d %d
    %d %d
    ",n,i,n*2,n^1^i),0;
    	return 0;
    }
    
  • 相关阅读:
    Python判断列表是否已排序的各种方法及其性能分析
    Python实现C代码统计工具(四)
    Python代码统计工具
    Python实现C代码统计工具(三)
    Python实现C代码统计工具(一)
    Python标准输出重定向
    为C函数自动添加跟踪语句
    Python2.7字符编码详解
    Python实现Linux命令xxd -i功能
    1124 Raffle for Weibo Followers (20 分)
  • 原文地址:https://www.cnblogs.com/stoorz/p/15388065.html
Copyright © 2011-2022 走看看