题面

ARC122D XOR Game

黑板上有

2

N

2N

2N 个数,第

i

i

i 个数为

A

i

A_i

Ai​。

O

I

D

\rm OID

OID(OneInDark) 和

H

I

D

HID

HID(HandInDevil) 玩一个游戏,总共进行

N

N

N 轮,每轮

  • H

    I

    D

    HID

    HID 选一个黑板上的数擦掉,令其为

    x

    x

    x 。

  • O

    I

    D

    \rm OID

    OID 再选一个黑板上的数擦掉,令其为

    y

    y

    y 。

  • 在笔记本上记下

    x

    y

    x\oplus y

    x⊕y 的值。

N

N

N 轮游戏之后,黑板上的数字会被擦光,笔记本上会记录有

N

N

N 个数字。最终的分数即为笔记本上最大的数字。

H

I

D

HID

HID 想让分数尽量大,

O

I

D

\rm OID

OID 想让分数尽量小。在两个人都采取最优策略的情况下,问最终的分数为多少?

1

N

2

1

0

5

1\leq N\leq 2\cdot 10^5

1≤N≤2⋅105,

0

A

i

<

2

30

0\leq A_i<2^{30}

0≤Ai​<230 。

题解

H

I

D

HID

HID 演算出最优方案时,他惊恐地发现:不论如何,整个游戏都被

O

I

D

\rm OID

OID 玩弄于指尖。

对于任何配对方案,

O

I

D

\rm OID

OID 都可以做到。不管

H

I

D

HID

HID 选的是什么数,

O

I

D

\rm OID

OID 只需要选与其配对的数就行了。所以我们要求的其实是找一种配对方案,使得异或后最大的值最小。

最大值最小,二分?

没有必要,这道题是求异或的最大值最小,和贪心算法、字典树的契合度极高。

经典的做法,先把所有数都放在字典树上再说。然后从最大的位开始考虑,尽量使得高位异或值

0

\tt0

0 ,我们就赢了。

当你遍历到字典树上某个点时(假设此时子树中有偶数个数字),会有两种情况:

  • 左子树和右子树的数字个数都是偶数,此时肯定可以在两棵子树中分别匹配完,不需要越过该节点匹配,这样是最优的。然后,由于后面的位数不确定,分别遍历左子树和右子树,取最大值
  • 左子树和右子树的数字个数都是奇数,此时不论怎么匹配,总得有一组数字是要越过该节点的,也就是说这一位上免不了有一个

    1

    \tt1

    1 了。那么就在这两棵子树上进行第二类遍历:每次遍历两个点

    {

    x

    ,

    y

    }

    \tt\{x,y\}

    {x,y},如果能够使当前位为

    0

    \tt0

    0 ,就分别遍历

    {

    x

    .

    s

    o

    n

    [

    0

    ]

    ,

    y

    .

    s

    o

    n

    [

    0

    ]

    }

    \tt\{x.son[0],y.son[0]\}

    {x.son[0],y.son[0]} 和

    {

    x

    .

    s

    o

    n

    [

    1

    ]

    ,

    y

    .

    s

    o

    n

    [

    1

    ]

    }

    \tt\{x.son[1],y.son[1]\}

    {x.son[1],y.son[1]} 取最小值,如果不行(其中不论如何都有一棵子树没有数字时),就只好把返回值加上这一位的

    1

    \tt1

    1,再遍历

    {

    x

    .

    s

    o

    n

    [

    0

    ]

    ,

    y

    .

    s

    o

    n

    [

    1

    ]

    }

    \tt\{x.son[0],y.son[1]\}

    {x.son[0],y.son[1]} 和

    {

    x

    .

    s

    o

    n

    [

    1

    ]

    ,

    y

    .

    s

    o

    n

    [

    0

    ]

    }

    \tt\{x.son[1],y.son[0]\}

    {x.son[1],y.son[0]} 取最小值加上。

最后的返回值就是答案了。

复杂度

Θ

(

N

l

o

g

A

)

\tt \Theta(N~log~A)

Θ(N log A) 。

CODE

#include<set>
#include<queue>
#include<bitset>
#include<cmath>
#include<ctime>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 400005
#define ENDL putchar('\n')
#define LL long long
#define DB double
#define lowbit(x) ((-x) & (x))
#define INF 0x3f3f3f3f
#define SI set<int>::iterator
LL read() {
LL f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s=='-')f = -f;s = getchar();}
while(s >= '0' && s <= '9') {x=x*10+(s-'0');s = getchar();}
return f * x;
}
int n,m,i,j,s,o,k;
int a[MAXN];
int tre[MAXN*30][2],cnt = 1;
int siz[MAXN*30];
void add(int x) {
int p = 1; siz[p] ++;
for(int i = 29;i >= 0;i --) {
int d = (x & (1<<i)) ? 1:0;
if(!tre[p][d]) tre[p][d] = ++ cnt;
p = tre[p][d]; siz[p] ++;
}return ;
}
int solve(int i,int a,int b,bool fl) {
if(i < 0) return 0;
if(!fl && siz[a] == 0) return 0;
if(siz[a] == 0 || siz[b] == 0) return (1<<(i+1))-1;
if(a == b) {
if(siz[tre[a][0]] & 1) {
return solve(i-1,tre[a][0],tre[a][1],1)+(1<<i);
}
return max(solve(i-1,tre[a][0],tre[a][0],0),solve(i-1,tre[a][1],tre[a][1],0));
}
else {
if((siz[tre[a][0]] > 0 && siz[tre[b][0]] > 0) || (siz[tre[a][1]] && siz[tre[b][1]])) {
return min(solve(i-1,tre[a][0],tre[b][0],1),solve(i-1,tre[a][1],tre[b][1],1));
}
return min(solve(i-1,tre[a][1],tre[b][0],1),solve(i-1,tre[a][0],tre[b][1],1)) + (1<<i);
}
}
int main() {
n = read();
for(int i = 1;i <= 2*n;i ++) {
a[i] = read();
add(a[i]);
}
printf("%d\n",solve(29,1,1,0));
return 0;
}

ARC122D XOR Game(博弈论?字典树,贪心)的更多相关文章

  1. HDU5715 XOR 游戏 二分+字典树+dp

    当时Astar复赛的时候只做出1题,赛后补题(很长时间后才补,懒真是要命),发现这是第二简单的 分析: 这个题,可以每次二分区间的最小异或和 进行check的时候用dp进行判断,dp[i][j]代表前 ...

  2. HDU 4825 Xor Sum(经典01字典树+贪心)

    Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total ...

  3. ACM学习历程—POJ 3764 The xor-longest Path(xor && 字典树 && 贪心)

    题目链接:http://poj.org/problem?id=3764 题目大意是在树上求一条路径,使得xor和最大. 由于是在树上,所以两个结点之间应有唯一路径. 而xor(u, v) = xor( ...

  4. CH 1602 - The XOR Largest Pair - [字典树变形]

    题目链接:传送门 描述在给定的 $N$ 个整数 $A_1, A_2,\cdots,A_N$ 中选出两个进行xor运算,得到的结果最大是多少? 输入格式第一行一个整数 $N$,第二行 $N$ 个整数 $ ...

  5. HDU-4825 Xor Sum,字典树好题!

    Xor Sum 一遍A了之后大呼一声好(keng)题!debug了两小时~~~~百度之星资格赛,可以. 题意:给你一个n个元素的数组,m次查询,每次输入一个数k要求从数组中找到一个数与k异或值最大,输 ...

  6. NEUOJ711 异星工厂 字典树+贪心

    题意:你可以收集两个不相交区间的权值,区间权值是区间异或,问这两个权值和最大是多少 分析:很多有关异或求最大的题都是利用01字典树进行贪心,做这个题的时候我都忘了...最后是看别人代码的时候才想起来这 ...

  7. HDU 5536 Chip Factory 字典树+贪心

    给你n个数,a1....an,求(ai+aj)^ak最大的值,i不等于j不等于k 思路:先建字典树,暴力i,j每次删除他们,然后贪心找k,再恢复i,j,每次和答案取较大的,就是答案,有关异或的貌似很多 ...

  8. hdu4825 01字典树+贪心

    从高位向低位构造字典树,因为高位得到的数更大. AC代码: #include<cstdio> using namespace std; typedef long long LL; cons ...

  9. HDU--5269 ZYB loves Xor I (字典树)

    题目电波: HDU--5269 ZYB loves Xor I 首先我们先解决 ai xor aj 每个数转化为二进制  我们用字典树统计 每个节点 0 和 1 的出现的个数 #include< ...

  10. HDU 5715 XOR 游戏 二分+字典树

    XOR 游戏 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5715 Description 众所周知,度度熊喜欢XOR运算(XOR百科). 今天,它 ...

随机推荐

  1. AcWing-1022

    题解借鉴两位大佬的解析 墨染空 && 野生铅笔 本题是一道 01背包 的扩展题 -- 二维费用01背包问题 把 野生宝可梦 看做物品,则捕捉他需要的 精灵球 个数就是第一费用,战斗皮神 ...

  2. 开源流程引擎osworkflow、jbpm、activiti、flowable、camunda哪个好?

    市场上比较有名的开源流程引擎有osworkflow.jbpm.activiti.flowable.camunda.其中:Jbpm4.Activiti.Flowable.camunda四个框架同宗同源, ...

  3. 【Spring】AOP实现原理(二):Advisor获取

    @EnableAspectJAutoProxy @EnableAspectJAutoProxy注解可以用来开启AOP,那么就从@EnableAspectJAutoProxy入手学习一下Spring A ...

  4. # 【由浅入深_打牢基础】WEB缓存投毒(上)

    image-20220611092344882 [由浅入深_打牢基础]WEB缓存投毒(上) 1. 什么是WEB缓存投毒 简单的来说,就是利用缓存将有害的HTTP响应提供给用户 什么是缓存,这里借用Bu ...

  5. 运行时应用自我保护(RASP):应用安全的自我修养

    应用程序已经成为网络黑客想要渗透到企业内部的绝佳目标. 因为他们知道如果能发现并利用应用程序的漏洞,他们就有超过三分之一的机会成功入侵. 更重要的是,发现应用程序漏洞的可能性也很大. Contrast ...

  6. WPF开发随笔收录-DrawingVisual绘制高性能曲线图

    一.前言 项目中涉及到了心率监测,而且数据量达到了百万级别,通过WPF实现大数据曲线图时,尝试过最基础的Canvas来实现,但是性能堪忧,而且全部画出来也不实际.同时也尝试过找第三方的开源库,但是因为 ...

  7. RPA供应链管制单修改机器人

    背景:供应链环节中,研发物料时而因为市场缺货等原因无法采购,资材部需登入系统修改物料管制单. 操作流程:登录PDM系统中读取数据.登录ERP系统中更新数据. 人工操作:每日耗时3.5小时,出现一定比例 ...

  8. iftop使用

    在linux中监控系统资源.进程.内存占用等信息,可以使用top命令. 查看网络状态可以使用netstat工具. 如果想查看实时的网络流量,监控TCP/IP连接等,则可以使用iftop工具. 一.if ...

  9. UiPath Level3讲解

    匠厂出品,必属精品   Uipath中文社区qq交流群:465630324 uipath中文交流社区:https://uipathbbs.com RPA之家qq群:465620839 第一课--UiP ...

  10. Python自动化办公:批量将文件按分类保存,文件再多,只需一秒钟解决

    序言 (https://jq.qq.com/?_wv=1027&k=GmeRhIX0) 当我们电脑里面的文本或者或者文件夹太多了,有时候想找到自己想要的文件,只能通过去搜索文件名,要是名字忘记 ...