D. Ehab and the Expected XOR Problem(构造前缀数组)

又是神仙题。

不过发现1900分的题很多都是转化为前缀(后缀)和数组来解决问题的

A , A s A数组不好构造,考虑构造A的前缀异或数组s

a i = s i s i 1 那么有a_i=s_i{\oplus} s_{i-1}

那么现在就是看这个s数组的限制

. , s [ 1 , 1 < < n ) Ⅰ.异或后值域不变,所以s数组也取[1,1<<n)

. 0 s Ⅱ.由于不出现子段异或和为0,所以s数组中任意元素不相等

, [ 1 , 1 < < n ) 1 换言之,[1,1<<n)中的数最多用1次

. s s i , s i x , x Ⅲ.若s数组出现了s_i,就不能出现s_i\oplus{x},这就保证没有字段异或为x

, w , w x \color{Red}那么,由于选w,就会删去w\oplus{x}

w , w x 且对于不同的w,删去的w\oplus{x}都是不同的

, [ 1 , 1 < < n ) 说明,[1,1<<n)中的元素我们可以选一半

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
#define quickly ios::sync_with_stdio(false)
bool vis[1<<18];
int n,x;
vector<int>ans;
int main()
{
	quickly;
	cin >> n >> x;
	vis[x]=1;
	ans.push_back(0);
	for(int i=1;i< (1<<n) ;i++)
	{
		if( vis[i] )	continue;
		ans.push_back(i);//选i,就不能选i^x
		vis[i]=vis[i^x]=1; 
	}
	cout << ans.size()-1 << endl;
	for(int i=1;i<ans.size();i++)	
		cout << ( ans[i]^ans[i-1] ) << " ";
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/jziwjxjd/article/details/107743030