ABC249G Xor Cards
好菜啊,ABC 都不会做。
考虑二进制的大小,我们可以利用钦定前若干位相同,下一位不同的方式来决定大小。考虑此时的小于等于 \(k\) ,实际上可以看成前若干位异或和等于一个钦定值的限制。然后对于另一个维度,我们则也是可以利用试错法来找到最大情况,实际上也是可以看成只考虑前若干位异或和等于一个钦定值的情况。
于是我们就可以愉快地利用线性基解决这个问题啦。
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5,M=30;
int n;
long long k,a[N],b[N];
struct Linear_Basis{
int cnt=0;
long long f[M*2];
void clear(){
cnt=0;
for(int i=0;i<60;++i) f[i]=0;
}
void insert(long long x){
for(int i=0;i<60;++i){
if(!((x>>i)&1)) continue;
if(f[i]) x^=f[i];else return f[i]=x,void();
}
cnt++;
}
bool check(long long x){
if(x==0) return cnt;
for(int i=0;i<60;++i) if((x>>i)&1) x^=f[i];
return x==0;
}
}lb;
long long res=-1;
int main(){
// freopen("1.in","r",stdin);
cin>>n>>k;
for(int i=1;i<=n;++i) scanf("%lld%lld",&a[i],&b[i]);
for(int i=29;i>=0;--i){
if(!((k>>i)&1)) continue;
long long tmp=(k^(1<<i)),TMP=0;
tmp=(tmp>>i)<<i;
for(int j=29;j>=0;--j){
lb.clear();
for(int c=1;c<=n;++c){
long long A=((a[c]>>i)<<i);
long long B=((b[c]>>j)<<j);
lb.insert((A<<30)|B);
}
if(lb.check((tmp<<30)|(TMP^(1<<j)))) TMP^=(1<<j);
}
lb.clear();
for(int c=1;c<=n;++c){
long long A=((a[c]>>i)<<i);
long long B=b[c];
lb.insert((A<<30)|B);
}
if(lb.check((tmp<<30)|TMP)) res=max(res,TMP);
}
{
long long tmp=k,TMP=0;
for(int j=29;j>=0;--j){
lb.clear();
for(int c=1;c<=n;++c){
long long A=(a[c]);
long long B=((b[c]>>j)<<j);
lb.insert((A<<30)|B);
}
if(lb.check((tmp<<30)|(TMP^(1<<j)))) TMP^=(1<<j);
}
lb.clear();
for(int c=1;c<=n;++c){
long long A=a[c];
long long B=b[c];
lb.insert((A<<30)|B);
}
if(lb.check((tmp<<30)|TMP)) res=max(res,TMP);
}
printf("%lld\n",res);
return 0;
}