CF1918C XOR-distance 题解

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;
} 
posted @ 2025-02-14 18:32  w9095  阅读(11)  评论(0)    收藏  举报