XOR Partition

题目描述

For a set of integers $ S $ , let's define its cost as the minimum value of $ x \oplus y $ among all pairs of different integers from the set (here, $ \oplus $ denotes bitwise XOR). If there are less than two elements in the set, its cost is equal to $ 2^{30} $ .

You are given a set of integers $ {a_1, a_2, \dots, a_n} $ . You have to partition it into two sets $ S_1 $ and $ S_2 $ in such a way that every element of the given set belongs to exactly one of these two sets. The value of the partition is the minimum among the costs of $ S_1 $ and $ S_2 $ .

Find the partition with the maximum possible value.

输入格式

The first line contains $ n $ ( $ 2 \le n \le 200000 $ ) — the number of elements in the set.

The second line contains $ n $ distinct integers $ a_1 $ , $ a_2 $ , ..., $ a_n $ ( $ 0 \le a_i < 2^{30} $ ) — the elements of the set.

妙妙题。

二分出来 \(m\),然后去看 \(a_i\oplus a_j<m\) 的所有 \(i,j\) 是不是组成二分图。明显要黑白染色。

如何知道一个数列中最小的 \(a_x\oplus a_y(x\ne y)\)? 有两种方法,而这两种方法衍生出这题的两种做法。

1,字典树

这个东西可以用字典树求。

考虑用字典树优化暴力建图。在跑字典树的途中,向小于 \(m\) 的所有子树连边,会连 \(\log n\) 次。

但是我不能连向自己所在的节点。所以要前后缀加上可持久化字典树就可以了。复杂度 \(O(nlog^2n)\),这是我考场上想到的方法,但是没写。

这题还有另一个单 log 的字典树做法。但没看懂

2

将 \(a\) 从小到大排序后 \(\min\limits_{i=1}^{n-1} a_i\oplus a_{i+1}\) 就是答案。因为异或存在性质:如果 \(x<y<z\),则 \(\min(x\oplus y,y\oplus z)<x\oplus z\)

这里也一样,将 \(a\) 从小到大排序后,如果 \(a_i\oplus a_{i+j}<m(j\ge 4)\),那么一定无解。考虑 $a_{i}\oplus a_{i+j} $ 的最高位,中间夹的这五个数可能是 \(\{0,0,0,0,1\},\{0,0,0,1,1\},\{0,0,1,1,1\},\{0,1,1,1,1\}\),然后这五种都存在三元环。

考虑一个 \(a_i\),我们只让他和 \(a_{i+1},a_{i+2},a_{i+3}\) 去连边。但是这样好像还是会有一个问题,如何证明这样连边合法的情况下,不存在连了后面的边后才会出现非法情况。但是这样做是能过的。希望有大佬可以给个证明或 hack。OI比赛中还是打 Trie 计算除了前三个是否存在 \(a_i\oplus a_j<m\) 或者打拍比较保险。

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,m,a[N],col[N],fl,e_num,hd[N],l=1,r=(1<<30)-1,id[N],p[N];
struct edge{
int v,nxt;
}e[N<<3];
void add_edge(int u,int v)
{
e[++e_num]=(edge){v,hd[u]};
hd[u]=e_num;
}
int read()
{
int s=0;
char ch=getchar();
while(ch<'0'||ch>'9')
s=s*10+ch-48,ch=getchar();
while(ch>='0'&&ch<='9')
s=s*10+ch-48,ch=getchar();
return s;
}
void dfs(int x)
{
for(int i=hd[x];i;i=e[i].nxt)
{
if(!~col[e[i].v])
col[e[i].v]=col[x]^1,dfs(e[i].v);
else if(col[e[i].v]^1^col[x])
fl=1;
}
}
int ok(int x)
{
memset(hd,e_num=fl=0,sizeof(hd));
memset(col,-1,sizeof(col));
for(int i=1;i<=n;i++)
for(int j=1;j<=3&&j+i<=n;j++)
if((a[i]^a[i+j])<x)
add_edge(i,i+j),add_edge(i+j,i);
for(int i=1;i<=n;i++)
if(!~col[i])
col[i]=0,dfs(i);
return fl^1;
}
int cmp(int x,int y)
{
return a[x]<a[y];
}
int main()
{
n=read();
if(n==2)
return puts("01"),0;
for(int i=1;i<=n;i++)
a[i]=read(),id[i]=i;
sort(id+1,id+n+1,cmp);
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
p[id[i]]=i;
while(l<=r)
{
int md=l+r>>1;
if(ok(md))
l=md+1;
else
r=md-1;
}
ok(r);
for(int i=1;i<=n;i++)
putchar(col[p[i]]+48);
}

[CF1849F] XOR Partition的更多相关文章

  1. ARC 066D Xor Sum AtCoder - 2272 (打表找规律)

    Problem Statement You are given a positive integer N. Find the number of the pairs of integers u and ...

  2. Partition:增加分区

    在关系型 DB中,分区表经常使用DateKey(int 数据类型)作为Partition Column,每个月的数据填充到同一个Partition中,由于在Fore-End呈现的报表大多数是基于Mon ...

  3. Partition:Partiton Scheme是否指定Next Used?

    在SQL Server中,为Partition Scheme多次指定Next Used,不会出错,最后一次指定的FileGroup是Partition Scheme的Next Used,建议,在执行P ...

  4. Partition:分区切换(Switch)

    在SQL Server中,对超级大表做数据归档,使用select和delete命令是十分耗费CPU时间和Disk空间的,SQL Server必须记录相应数量的事务日志,而使用switch操作归档分区表 ...

  5. sql 分组取最新的数据sqlserver巧用row_number和partition by分组取top数据

    SQL Server 2005后之后,引入了row_number()函数,row_number()函数的分组排序功能使这种操作变得非常简单 分组取TOP数据是T-SQL中的常用查询, 如学生信息管理系 ...

  6. Oracle Partition Outer Join 稠化报表

    partition outer join实现将稀疏数据转为稠密数据,举例: with t as (select deptno, job, sum(sal) sum_sal from emp group ...

  7. SQLServer中Partition By 函数的使用

    今天群里看到一个问题,在这里概述下:查询出不同分类下的最新记录.一看这不是很简单的么,要分类那就用Group By;要最新记录就用Order By呗.然后在自己的表中试着做出来: 首先呢我把表中的数据 ...

  8. [LeetCode] Maximum XOR of Two Numbers in an Array 数组中异或值最大的两个数字

    Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Find the maximum re ...

  9. [LeetCode] Partition Equal Subset Sum 相同子集和分割

    Given a non-empty array containing only positive integers, find if the array can be partitioned into ...

  10. [LeetCode] Partition List 划分链表

    Given a linked list and a value x, partition it such that all nodes less than x come before nodes gr ...

随机推荐

  1. Windows校验文件MD5和SHA值的方法

    1.需求背景 下载或传输文件后,需要计算文件的MD5.SHA256等校验值,以确保下载或传输后的文件和源文件一致 2.校验方法 如上图所示,可以使用Windows自带的certutil命令来计算一个文 ...

  2. 【日常踩坑】解决 pip 安装第三方包时因 SSL 报错

    目录 踩坑 什么是 SSL ? 为什么会报错 解决办法 1. 临时关闭代理.VPN 或者网络抓包等软件 2. 通过镜像的 HTTP 源来避免 SSL 认证问题 3. 切换至低版本 pip 参考资料 踩 ...

  3. 从原理聊 JVM(五):JVM 的编译过程和优化手段

    一.前端编译 前端编译就是将Java源码文件编译成Class文件的过程,编译过程分为4步: 1 准备 初始化插入式注解处理器(Annotation Processing Tool). 2 解析与填充符 ...

  4. GrapeCity Documents V6.0 Update 2发布,新增支持SpreadJS的.sjs文件格式

    近日,GrapeCity Documents 正式迎来其V6.2 的发布更新,能够支持 SpreadJS 中 .sjs 类型的文件.这一重大更新将为用户带来更多地惊喜. .sjs文件有两个关键优势:空 ...

  5. 在线问诊 Python、FastAPI、Neo4j — 创建药品节点

    目录 前提条件 创建节点 Demo 准备数据 创建药品标签节点 在线问诊 Python.FastAPI.Neo4j - 创建节点 Neo4j 节点的标签可以理解为 Java 中的实体. 根据常规流程: ...

  6. 【.NET8】访问私有成员新姿势UnsafeAccessor(上)

    前言 前几天在.NET性能优化群里面,有群友聊到了.NET8新增的一个特性,这个类叫UnsafeAccessor,有很多群友都不知道这个特性是干嘛的,所以我就想写一篇文章来带大家了解一下这个特性. 其 ...

  7. Spring Boot 目录遍历--表达式注入--代码执行--(CVE-2021-21234)&&(CVE-2022-22963)&&(CVE-2022-22947)&&(CVE-2022-2296)

    Spring Boot 目录遍历--表达式注入--代码执行--(CVE-2021-21234)&&(CVE-2022-22963)&&(CVE-2022-22947)& ...

  8. 18.2 使用NPCAP库抓取数据包

    NPCAP 库是一种用于在Windows平台上进行网络数据包捕获和分析的库.它是WinPcap库的一个分支,由Nmap开发团队开发,并在Nmap软件中使用.与WinPcap一样,NPCAP库提供了一些 ...

  9. 1.NoSQL-lesson14-MongoDB核心技术-运维篇

    逻辑结构 Mongodb 逻辑结构 MySQL逻辑结构 库database 库 集合(collection) 表 文档(document) 数据行 选择之所以称为为选择,肯定是痛苦的! ------& ...

  10. CF1854E Games Bundles 题解

    乱搞题 设个 \(dp[i]\) 表示和为 \(i\) 的子序列个数,那么转移是容易的, \(dp[j]+=dp[j-i]\) ,然后就判下 \(dp[60]+dp[60-i]\) 是否大于 \(m\ ...