[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;
}
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号