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. 新一代Kerberos攻击 钻石票据与蓝宝石票据

    新一代Kerberos攻击 | 钻石票据与蓝宝石票据 0x01 前言 在了解票据攻击的过程中,看见了一篇文章使用Rubeus进行钻石票据攻击.但是没有原理,于是抱着学习的心态在Google上寻找文章发 ...

  2. 基于Supabase开发公众号接口

    在<开源BaaS平台Supabase介绍>一文中我们对什么是BaaS以及一个优秀的BaaS平台--Supabase做了一些介绍.在这之后,出于探究的目的,我利用一些空闲时间基于Micros ...

  3. Java 设计模式实战系列—单例模式

    本文首发公众号:小码A梦 单例模式是设计模式中最简单一个设计模式,该模式属于创建型模式,它提供了一种创建实例的最佳方式. 单例模式的定义也比较简单:一个类只能允许创建一个对象或者实例,那么这个类就是单 ...

  4. Codeforces 1463D Pairs

    题意 对于数字\(1\)~\(2n\),可以构造出\(n\)个二元组,对于\(n\)个二元组,选择一个数组\(x\),留下\(x\)个二元组的最小值,留下\(n-x\)个二元组的最大值,其构成了一个集 ...

  5. 安卓APK资源混淆加密重签名工具 (安卓APK加固, 代码混淆, 资源混淆,保护APK)

    安卓APK资源混淆加密重签名工具,可以对安卓APK文件的代码和资源文件进行混淆加密处理,可以对安卓APK文件进行加固,对代码和资源文件进行混淆,重新签名等功能. 可以保护APK,增加破解难度等功能. ...

  6. Spring扩展接口(1):ApplicationContextInitializer

    在此系列文章中,我总结了Spring扩展接口,以及各个扩展点的使用场景.并整理出一个bean在spring中从被加载到初始化到销毁的所有可扩展点的顺序调用图.这样,我们也可以看到bean是如何一步步加 ...

  7. Strimzi Kafka Bridge(桥接)实战之一:简介和部署

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 关于<Strimzi Kafka Bridge( ...

  8. 其它——ASCII码,Unicode和UTF-8编码

    文章目录 一 ASCII码 二 非ASCII编码 三 Unicode 3.1 Unicode存在的问题 3.2 它们造成的结果是 四 UTF-8 4.1 UTF-8 特点 4.2 UTF-8 的编码规 ...

  9. Python开发之Django框架

    一. Django框架 01.网络软件开发架构演变过程 02.HTTP协议讲解 03.web应用与框架介绍及手撸web框架 04.Django入门项目创建与必会三板斧 05.Django静态文件配置与 ...

  10. Oracle中的substr()函数和INSTR()函数和mysql中substring_index函数字符截取函数用法:计算BOM系数用量拼接字符串*计算值方法

    最近一直在研究计算产品BOM的成本系数,将拼接的元件用量拼接后拆分计算是个问题,后来受到大佬在mysql中截取字符串的启发在oracle中以substr和instr实现了  1.以下是我在mysql中 ...