Codeforces 1748 D

这场D还是很有趣的,值得探讨。

首先a|x,b|x是两个数,不相同时不太好做,所以我们能否找到一个x,满足a|x=b|x并且都是d的倍数呢?

然后我们让d特殊一些——我们先解决d是奇数的问题。

只要x包含a,b中所有为1的位,并且是d的倍数就可以了,也就是x&(a|b)=(a|b)并且x0modd

那么若(a|b)的第i位为1,我们可以让x+=2i×d,这样xd的倍数,并且由于d的最后一位为1d是奇数),可以保证x的第i位也是1,并且不改变第i位之前的数字。

程序实现就是下面这样子的:

for(ll i=0;i<30;i++) {
    if(((a|b)&(1ll<<i))>=1) {
	if((x&(1ll<<i))==0) {
		x+=(1ll<<i)*d;
	}
    }
}

那么d是偶数呢?此时d的有一系列后缀0。如果(a|b)在这段内有1,那么一定无解;否则我们可以先去除掉这些后缀0,到最后输出答案时加上即可。

可以发现,x是不超过230×d的,故满足题中x260的条件。

时间复杂度为O(Tlogn)

完整代码:

#include<bits/stdc++.h>
#define debug(...) std::cerr<<#__VA_ARGS__<<" : "<<__VA_ARGS__<<std::endl

using ll=long long;

void solve() {
	ll a,b,d;
	scanf("%lld%lld%lld",&a,&b,&d);
	ll shift=0,res=0;
	while(!(d&1ll)) d>>=1ll,shift++;
	for(ll i=0;i<shift;i++) {
		if((a&(1ll<<i))||(b&(1ll<<i))) {
			printf("-1\n");
			return;
		}
	}
	a>>=shift; b>>=shift;
	for(ll i=0;i<30;i++) {
		if(((a|b)&(1ll<<i))>=1) {
			if((res&(1ll<<i))==0) {
				res+=(1ll<<i)*d;
			}
		}
	}
	printf("%lld\n",res<<shift);
}

int main() {
	int T;
	scanf("%d",&T);
	while(T--) {
		solve();
	}
	return 0;
}
posted @   Nastia  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示