CF1787E The Harmonization of XOR 题解

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

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

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

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

证明:设 Bx 的最高位,即 x 的第 B 位为 1(类似 popcount)
M 是从 1n 的数字,并且使得第 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 @   jiangtaizhe001  阅读(48)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示