CF1918C XOR-distance 题解
考虑对 \(a,b\) 进行二进制分解,在二进制位中进行计算。
设 \(a_i\) 表示数 \(a\) 二进制第 \(i\) 位。如果 \(a_i=b_i\),则不需要对 \(x_i\) 进行任何构造。但如果 \(a_i\) 不等于 \(b_i\),把 \(x_i\) 置为 \(1\) 只能改变 \(a_i\) 和 \(b_i\) 的大小关系,不能使其相等。
所以,我们从高位开始考虑,因为高位影响一定超过低位影响,所以不需要管对低位的影响,计算比较方便。首先找到第一个 \(a_i\) 与 \(b_i\) 的大小关系,根据进制位定义,可以推出高位影响一定超过低位影响,\(a\) 和 \(b\) 的大小关系就已经确定了。接下来,就是在下面的几位中,尽量使较大的数较小,较小的数较大即可,不需要管对低位的影响。
注意在修改时 \(x\) 的值不能超过 \(r\)。
时间复杂度为 \(O(t\log n)\),可以通过。
#include <bits/stdc++.h>
using namespace std;
long long t,n,m,r,a[200][2];
int main()
{
scanf("%lld",&t);
while(t--)
{
long long flag=-1,ans=0;
scanf("%lld%lld%lld",&n,&m,&r);
for(int i=0;i<=63;i++)
{
if(n&((long long)1<<i))a[i][0]=1;
else a[i][0]=0;
if(m&((long long)1<<i))a[i][1]=1;
else a[i][1]=0;
}
for(int i=63;i>=0;i--)
{
if(a[i][0]==a[i][1])continue;
if(flag==-1)
{
if(a[i][0]>a[i][1])flag=1;
else if(a[i][0]<a[i][1])flag=0;
ans+=((long long)1<<i);
}
else if(a[i][0]>a[i][1])
{
if(flag==1&&r>=((long long)1<<i))r-=((long long)1<<i),ans-=((long long)1<<i);
else if(flag==0)ans-=((long long)1<<i);
else if(flag==1)ans+=((long long)1<<i);
}
else if(a[i][0]<a[i][1])
{
if(flag==0&&r>=((long long)1<<i))r-=((long long)1<<i),ans-=((long long)1<<i);
else if(flag==1)ans-=((long long)1<<i);
else if(flag==0)ans+=((long long)1<<i);
}
}
printf("%lld\n",ans);
}
return 0;
}

浙公网安备 33010602011771号