description
给定 n n n 个数 { a i } \{a_i\} {ai},要求从中选出两个不同的数 x , y x,y x,y,使得 x o p y x\ op\ y x op y 最大。
o p = o r , x o r , a n d op=or,xor,and op=or,xor,and
n ≤ 1 0 6 , a i ≤ 1 0 6 n\leq 10^6,a_i\leq10^6 n≤106,ai≤106
solution
- x o r xor xor
我们对于所有的数二进制形式建一棵 t r i e trie trie,然后枚举一个数,在另一个上面贪心做就好了
O ( σ n ) O(\sigma n) O(σn)
- o r or or
考虑枚举每一个数,然后对于 0 0 0 的位,看有没有一个数能够依次满足从高到低的每一位,如果有就填上,如果没有就空过去
O ( σ n ) O(\sigma n) O(σn)
- a n d and and
从高到低枚举每一位,如果这一位上现在可以选的为 1 1 1 的数量 ≥ 2 \geq 2 ≥2 就选上,删掉所有这一位是 0 0 0 的,否则不管
O ( σ n ) O(\sigma n) O(σn)
#include<iostream>
#include<cstring>
#include<cassert>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<time.h>
#include<algorithm>
#include<climits>
using namespace std;
# define Rep(i,a,b) for(register int i=a;i<=b;i++)
# define _Rep(i,a,b) for(register int i=a;i>=b;i--)
# define RepG(i,u) for(int i=head[u];~i;i=e[i].next)
typedef long long ll;
const int N=(1<<20)+5;
template<typename T> void read(T &x){
x=0;int f=1;
char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+c-'0';
x*=f;
}
int t,n,op;
namespace And{
int a[N];
bool flag[N];
void solve(){
Rep(i,1,n)read(a[i]),flag[i]=true;
int res=0;
_Rep(s,19,0){
int cnt=0;
Rep(i,1,n)
if(a[i]>>s&1&&flag[i])cnt++;
if(cnt>=2){
res|=1<<s;
Rep(i,1,n)
if(!(a[i]>>s&1))flag[i]=false;
}
}
printf("%d\n",res);
}
}
namespace Or{
int a[N],sum[N];
void solve(){
memset(sum,0,sizeof(sum));
Rep(i,1,n)read(a[i]),sum[a[i]]++;
int res=0;
Rep(s,0,19)
for(int i=0;i<1<<20;i++)
if(i>>s&1)sum[i^(1<<s)]+=sum[i];
Rep(i,1,n){
int now=a[i],yuzuki=0;
_Rep(s,19,0){
if(now>>s&1)continue;
yuzuki|=1<<s;
if(!sum[yuzuki])yuzuki^=1<<s;
}
now|=yuzuki;
res=max(res,now);
}
printf("%d\n",res);
}
}
namespace Xor{
int trie[N][2],tot;
int a[N];
void insert(int x){
int u=0;
_Rep(i,19,0){
int j=x>>i&1;
if(!trie[u][j])trie[u][j]=++tot;
u=trie[u][j];
}
}
int ask(int x){
int u=0,res=0;
_Rep(i,19,0){
int j=x>>i&1;
j^=1;
if(trie[u][j]){
res|=1<<i;
u=trie[u][j];
}
else u=trie[u][j^1];
}
return res;
}
void solve(){
memset(trie,0,sizeof(trie));
tot=0;
int res=0;
Rep(i,1,n)read(a[i]),insert(a[i]);
Rep(i,1,n)res=max(res,ask(a[i]));
printf("%d\n",res);
}
}
int main()
{
read(t);
while(t--){
read(n),read(op);
if(op==1)And::solve();
if(op==2)Xor::solve();
if(op==3)Or::solve();
}
return 0;
}
/*
3
5 1
1 4 5 7 9
5 2
2 3 4 5 7
5 3
9 5 4 2 1
*/