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

    题目描述

    题解

    先想到的奇数,后来发现偶数也可以

    不合法的情况:n是2的幂,因为其他的数没有最高位

    首先有一个性质,2k xor 2k+1=1

    也就是说2k xor 2k+1 xor 2k+2 xor 2k+3=0

    当n模4余3时直接按1~n,1~n排成一行即可(第一项视作xor 0)这样1xor到n=0,去掉一项后刚好等于自己

    当n模4余1时把n-1和n提出来按n-1,n,1,n-1,1的顺序连边即可,剩下的排成一行即可

    考虑n是偶数,不考虑n就是奇数的情况

    如果是一条链(%4=0),那么把n-1和n xor n-1通过交换连在一起,然后连n,n-1,n xor (n-1),n即可

    如果模4=2,那么把1和n xor (n-2) xor 1连在一起,然后连n,n-2,1,n xor (n-2) xor 1,n即可

    code

    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define ll long long
    //#define file
    using namespace std;
    
    int n,i,j,k,l,x;
    int jh(int t,int x,int y) {return t==x?y:(t==y?x:t);}
    
    int main()
    {
    	#ifdef file
    	freopen("agc035c.in","r",stdin);
    	#endif
    	
    	scanf("%d",&n);
    	if (pow(2,floor(log2(n)))==n) {printf("No
    ");return 0;}
    	
    	printf("Yes
    ");
    	if (!(n&1))
    	{
    		if (!(((n-1)+1)&2))
    		{
    			x=n^(n-1);
    			fo(i,1,n-2) printf("%d %d
    ",jh(i,1,x),jh(i+1,1,x));
    			printf("%d %d
    ",jh(n-1,1,x),jh(n+1,1+n,x+n));
    			fo(i,1,n-2) printf("%d %d
    ",jh(i+n,1+n,x+n),jh(i+1+n,1+n,x+n));
    			printf("%d %d
    ",n,n-1),printf("%d %d
    ",x+n,n+n);
    		}
    		else
    		{
    			x=n^(n-2)^1;
    			fo(i,1,n-4) printf("%d %d
    ",jh(i,2,x),jh(i+1,2,x));
    			fo(i,1,n-4) printf("%d %d
    ",jh(i+n,2+n,x+n),jh(i+1+n,2+n,x+n));
    			printf("%d %d
    ",jh(n-3,2,x),jh(n+1,2+n,x+n));
    			printf("%d %d
    ",n-2,n-1),printf("%d %d
    ",n-1,1),printf("%d %d
    ",1,n-2+n),printf("%d %d
    ",n-2+n,n-1+n);
    			printf("%d %d
    ",n,n-2+n),printf("%d %d
    ",x,n+n);
    		}
    	}
    	else
    	if (!((n+1)&2))
    	{fo(i,1,n+n-1) printf("%d %d
    ",i,i+1);}
    	else
    	{
    		fo(i,1,n-3) printf("%d %d
    ",i,i+1);
    		fo(i,1,n-3) printf("%d %d
    ",i+n,i+1+n);
    		printf("%d %d
    ",n-2,n+1);
    		printf("%d %d
    ",n-1,n),printf("%d %d
    ",n,1),printf("%d %d
    ",1,n-1+n),printf("%d %d
    ",n-1+n,n+n);
    	}
    	
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    sizeof和strlen区别
    Reverse Words in a String
    删除字符串中重复的字符
    Reverse String
    数组中一个数字出现的次数超过了数组长度的一半,请找出这个数
    输出数组中大于等于左边所有数且小于等于右边所有数的元素
    java获取数据库里表的名字
    [转]C++编写Config类读取配置文件
    c# App.Config详解
    pitch yaw roll是什么
  • 原文地址:https://www.cnblogs.com/gmh77/p/12873391.html
Copyright © 2011-2022 走看看