[ARC122D]XOR Game
Posted Tan_tan_tann
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[ARC122D]XOR Game相关的知识,希望对你有一定的参考价值。
XOR Game
题解
再次读错题,当场死亡
首先,题目的意思是,从长度为
2
n
2n
2n序列中匹配
n
n
n对数,并将匹配的两个数异或,使得的异或值最大值最小。
我们可以先考虑建一棵
t
r
i
e
trie
trie树出来,从根节点开始遍历。
如果遍历到一个节点它的左右儿子的数的数量都是偶数,那么如果Alice选择左子树的点,Bob肯定也会选择左节点的点,如果Alice选择右子树的点,Bob也会选择有节点的点,所以二进制的这一位始终为 0 0 0,继续遍历子树。
如果两者都为奇数,那么我们肯定会有一个左子树的点匹配到右子树的点,而Bob肯定会让这个值最小。
假设最小的匹配为
(
x
,
y
)
(x,y)
(x,y)如果Alice选的不是
x
x
x或
y
y
y,Bob就会选择与那个点同子树的点,只有选到
x
,
y
x,y
x,y中的一个,Bob才会选另一个。
而
x
x
x与
y
y
y匹配这一位肯定是
1
1
1,比其它都大,所以该节点的答案就是
x
x
x与
y
y
y匹配。
接下来的节点就没必要遍历了,其值肯定也比
x
x
x与
y
y
y匹配的小。
这样遍历完整棵树就可以得到答案了。
时间复杂度
O
(
n
l
o
g
a
)
O\\left(nlog\\,a\\right)
O(nloga)。
源码
#include<bits/stdc++.h>
using namespace std;
#define MAXN 400005
#define lowbit(x) (x&-x)
#define reg register
#define mp make_pair
#define fir first
#define sec second
typedef long long LL;
typedef unsigned long long uLL;
const int INF=0x3f3f3f3f;
const int mo=1e9+7;
const int iv2=5e8+4;
const int lim=1000000;
const int jzm=1e6+7;
const int orG=3,invG=332748118;
const double Pi=acos(-1.0);
typedef pair<LL,LL> pii;
const double PI=acos(-1.0);
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){
_T f=1;x=0;char s=getchar();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
x*=f;
}
template<typename _T>
void print(_T x){if(x<0){x=(~x)+1;putchar('-');}if(x>9)print(x/10);putchar(x%10+'0');}
int gcd(int x,int y){return !y?x:gcd(y,x%y);}
int add(int x,int y){return x+y<mo?x+y:x+y-mo;}
int n,a[MAXN],ans,root,tmp;
class TrieTree{
public:
int tot,ch[MAXN*40][2],sum[MAXN*40];
void insert(int &rt,int val,int dp){
if(!rt)rt=++tot;sum[rt]++;if(dp<0)return ;
if(val&(1<<dp))insert(ch[rt][1],val,dp-1);
else insert(ch[rt][0],val,dp-1);
}
void match(int x,int y,int dp,int num){
if(dp<0){tmp=min(tmp,num);return ;}
if(ch[x][0]&&ch[y][0])match(ch[x][0],ch[y][0],dp-1,num);
if(ch[x][1]&&ch[y][1])match(ch[x][1],ch[y][1],dp-1,num);
if(!ch[x][0]&&ch[y][0])match(ch[x][1],ch[y][0],dp-1,num^(1<<dp));
if(!ch[x][1]&&ch[y][1])match(ch[x][0],ch[y][1],dp-1,num^(1<<dp));
}
void dosaka(int rt,int dp){
if(dp<0||!rt)return ;
if(sum[ch[rt][0]]&1)
tmp=INF,match(ch[rt][0],ch[rt][1],dp-1,(1<<dp)),ans=max(ans,tmp);
else dosaka(ch[rt][0],dp-1),dosaka(ch[rt][1],dp-1);
}
}T;
signed main(){
read(n);for(int i=1;i<=2*n;i++)read(a[i]);sort(a+1,a+n+1);
for(int i=1;i<=2*n;i++)T.insert(root,a[i],29);T.dosaka(root,29);
printf("%d\\n",ans);
return 0;
}
谢谢!!!
以上是关于[ARC122D]XOR Game的主要内容,如果未能解决你的问题,请参考以下文章
ARC工程使用不支持ARC的库以及非ARC工程使用ARC的库编译设置