CF1787E The Harmonization of XOR 题解

我甚至都忘记什么时候写的这玩意了。

由于异或满足交换律和结合律,所以首先需要保证 \(1\)\(n\) 所有数字异或和等于 \(k\) 组的异或和。
其次我们考虑到 \(x \oplus x \oplus x=x\),也就是说 \(3\) 组可以合并成 \(1\) 组,所以我们只需要最大化能够分的组数。

考虑最大化组数的一个方法:

  • 如果 \(x\) 存在,单独分组
  • 其余两两一组
  • 剩下的在一组

证明:设 \(B\)\(x\) 的最高位,即 \(x\) 的第 \(B\) 位为 \(1\)(类似 popcount)
\(M\) 是从 \(1\)\(n\) 的数字,并且使得第 \(B\) 位为 \(1\) 的数量,显然答案小于等于 \(M\),因为在每个组中,必须至少有一个数字表示第 \(B\) 位为 \(1\)
\(M\) 个数字异或 \(x\) 之后肯定更小,所以一定存在 \(M\) 组。

时间复杂度 \(O(n)\)

int n,k,x,p[maxn],vis[maxn];
int getsum(int x){ int i,s=0; for(i=1;i<=x;i++) s^=i; return s; }
struct JTZ{ int x,y; }a[maxn]; int cnt,now;
void work(){
	n=read(); k=read(); x=read(); int i; if((k&1)?getsum(n)!=x:getsum(n)){ puts("NO"); return; }
	cnt=now=0; for(i=1;i<=n;i++) p[i]=vis[i]=0;
	for(i=1;i<=n;i++){
		if(i==x) a[++cnt]=(JTZ){i,0},p[i]=1;
		if((i^x)<=n&&!p[i]&&!p[i^x]) p[i]=1,p[i^x]=1,a[++cnt]=(JTZ){i,i^x};
	} if(cnt<k){ puts("NO"); return; } puts("YES");
	for(i=1;i<k;i++){
		if(a[i].y) pc('2'),pc(' '),print(a[i].x),pc(' '),print(a[i].y),pc('\n'),now+=2;
		else pc('1'),pc(' '),print(a[i].x),pc('\n'),now++;
		vis[a[i].x]=vis[a[i].y]=1;
	} print(n-now),pc(' ');
	for(i=1;i<=n;i++) if(!vis[i]) print(i),pc(' ');
	pc('\n'); return;
}
posted @ 2023-01-31 11:07  jiangtaizhe001  阅读(47)  评论(0编辑  收藏  举报