agc031 C Differ by 1 Bit

传送门:
https://atcoder.jp/contests/agc031/tasks/agc031_c

题解:

考虑把x xor y,问题变成从0->x xor y

因为 2 n − 1 2^n-1 2n1是奇数,所有 x   x o r   y x~xor~y x xor y有偶数个1无解。

由于我们任意交换一下位是没有关系的,所以考虑就是要构造出:
000 … − > 111 ( k ( k 奇 数 ) 个 1 ) 00 … … 000…->111(k(k奇数)个1)00…… 000>111(k(k)1)00

s ( n , k ) s(n,k) s(n,k)表示有k个1时的答案。

当k=1时,显然有:
强制第一位为0,后面任意走完,可以通过n-1,k任意的情况推来
然后把第一位改为1,后面的倒着走即可走回后面全0

k>=3时

考虑固定第一位为0,后面走 s ( n − 1 , k − 2 ) s(n-1,k-2) s(n1,k2)

把第一位改为1,然后现在把后面的位视为全0(走的时候异或一下即可),走s(n-1,1),注意1的位置要移到n-k+1那里去。

#include
#include
#include
#include
#include
#define ll long long
#define db double
#define ld long double
#define pp printf
#define fo(i, x, y) for(int i = x, B = y; i <= B; i ++)
#define ff(i, x, y) for(int i = x, B = y; i <  B; i ++)
#define fd(i, x, y) for(int i = x, B = y; i >= B; i --)
#define pb push_back
#define sz size()
using namespace std;

vector<int> a[18][18];


int z[1 << 18];
int us[20], to[20];

void zh(int x, int y, int n) {
	ff(i, 0, n) us[i] = 0;
	ff(i, 0, n) {
		ff(j, 0, n) if((x >> i & 1) == (y >> j & 1) && !us[j])
			{ us[j] = 1; to[i] = j; break;}
	}
	ff(i, 0, 1 << n) {
		int s = 0;
		ff(j, 0, n) s += (i >> j & 1) * (1 << to[j]);
		z[i] = s;
	}
}

int n, x, y, c;

void pr(int x, int n) {
	fd(i, n - 1, 0) pp("%d", x >> i & 1); pp(" ");
}

int main() {
	freopen("a.in", "r", stdin);
	freopen("a.out", "w", stdout);
	n = 17;
	a[1][1].pb(0); a[1][1].pb(1);
	fo(i, 2, n) {
		int mx = 1 << (i - 1);
		ff(k, 0, a[i - 1][1].sz)
			a[i][1].pb(a[i - 1][1][k]);
		fd(k, a[i - 1][1].sz - 1, 0)
			a[i][1].pb(a[i - 1][1][k] + mx);
			
		for(int j = 3; j <= i; j += 2) {
			ff(k, 0, a[i - 1][j - 2].sz)
				a[i][j].pb(a[i - 1][j - 2][k]);
			int h = a[i - 1][j - 2][a[i - 1][j - 2].sz - 1];
			zh(1 << (i - 2), 1 << (i - j), i - 1);
			ff(k, 0, a[i - 1][1].sz)
				a[i][j].pb((z[a[i - 1][1][k]] ^ h) + (1 << (i - 1)));
		}
	}
	scanf("%d %d %d", &n, &x, &y);
	ff(i, 0, n) c += (x ^ y) >> i & 1;
	if(c % 2 == 0) {
		pp("NO\n"); return 0;
	}
	pp("YES\n");
	zh(a[n][c][a[n][c].sz - 1], x ^ y, n);
	ff(k, 0, a[n][c].sz) pp("%d ", z[a[n][c][k]] ^ x);
	
}

你可能感兴趣的:(构造题)