确实非常巧妙
注意到ai最大1000,k最大1000,所以ai⊕k最大是1023
所以直接暴力模拟k次,每次开个桶记录j这个数字出现了几次
那么第i次操作的桶怎么转移到i+1次的桶呢?
假设当前j这个数字在第i次操作后出现了w次
那么根据只对奇数异或,因为w个j是连成一片的
所以有w/2个j去异或,有w/2个j保留
特判如果有s个数比j大且s是偶数w是奇数,那么有w/2+1个j去异或
#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+20;
int n,k,x,a[maxn],f[maxn],t[maxn];
int main()
{
cin >> n >> k >> x;
for(int i=1;i<=n;i++) cin >> a[i],f[ a[i] ]++;
for(int i=1;i<=k;i++)
{
int s=0;//比j小的数量
for(int j=0;j<=1024;j++) t[j]=f[j];
for(int j=0;j<1024;j++)
{
if(f[j]==0) continue;
int shu=f[j]/2;
if(s%2==0&&f[j]%2==1) shu++;
//怎么理解?shu个j一定是连在一起的
//一般有shu/2个j在奇数位,但如果第一个j在奇数位且有奇数个j就要多加一个
t[j^x]+=shu,t[j]-=shu;
s+=f[j];
}
for(int j=0;j<1024;j++) f[j]=t[j];
}
int minn=1e9,maxx=0;
for(int i=0;i<1024;i++)
if(f[i])
{
maxx=max(maxx,i);
minn=min(minn,i);
}
cout<<maxx<<" "<<minn;
}