题解 P6824 【「EZEC-4」可乐】
提供一个考试时的奇怪做法。
首先显然这个聪明值不会超过
然后我们考虑一个 naive 的暴力,就是枚举这个范围的每个数,每次暴力统计
显然暴力的瓶颈在于判断是否可行,那我们可以考虑建一个 Trie 来维护二进制的
复杂度
注意题目条件中要求的是
5 10
4
1
14
13
13
这组数据给叉掉。
Code:
#include<bits/stdc++.h>
using namespace std;
const int N=1000005;
int n,k,ans,a[N],cnt[2];
int tot,sz[N*21],trie[N*21][2];
void insert(int x){
int p=0;
for(int k=21,c;k>=0;k--){
c=(x>>k)&1;
if(!trie[p][c])trie[p][c]=++tot;
p=trie[p][c];
sz[p]++;
}
}
int query(int x){
int ret=0,p=0;
bool flag=0;
for(int i=21,c;i>=0;i--){
c=(x>>i)&1;//x这一位的值
int t=(k>>i)&1;//k这一位的值
if(t==1)ret+=sz[trie[p][1-(c^t)]];//如果k这一位的值是1,那么这一位取1-(c^t)的时候一定可行,反之一定不可行
if(!trie[p][c^t]){flag=1;break;}//如果走不到就返回
p=trie[p][c^t];
}
if(!flag)ret+=sz[p];
return ret;
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)scanf("%d",&a[i]),insert(a[i]);
for(int i=0;i<2097152;i++){
ans=max(ans,query(i));
if(ans==n)break;
}
printf("%d\n",ans);
return 0;
}