t(t<=1e4)组样例,每次给定a,b,d(1<=a,b,d<2的30次方)
求是否存在一个x(0<=x<2的60次方),满足(a|x)是d的倍数,且(b|x)是d的倍数,
其中|为二进制下的or,存在的话输出任意一个x即可,如果不存在,输出-1
官方题解&rainboy&inszva代码
先判断不合法的情形,
如果d为偶数,此时a和b如果有一个为奇数,则肯定无解,a%d必有余数
否则令d/2,a/2,b/2,继续判断,中途无解提前退出,...,直到d为奇数,
d为奇数后,一定有解,即任意数都有解,此时不妨令x=a|b,
为x构造出解之后,(a|x)=x,(b|x)=x,x也是原问题的解,
等价于解同余方程
,
其中c为前面除以2的次数,两边同乘
即可还原成原来的式子
先移项,然后由于d为奇数,
,
可求2的逆元inv(2),实际上就是(d+1)/2,两侧同乘
即可得到t,
,代入即可求得x
- #include
- using namespace std;
- typedef long long ll;
- int t,a,b,c,d,v;
- int main(){
- cin>>t;
- while(t--){
- cin>>a>>b>>d;
- c=0;
- while(a%2==0 && b%2==0 && d%2==0){
- a/=2,b/=2,d/=2;
- c++;
- }
- if(d%2==0){
- cout<<-1<
- continue;
- }
- int inv=(d+1)/2;
- v=1;
- for(int i=0;i<30-c;++i){
- v=1ll*v*inv%d;
- }
- int r=((d-(a|b))%d+d)%d;
- ll x=1ll*v*r%d;
- a<<=c;b<<=c;
- cout<<((x<<30)|(a|b))<
- }
- return 0;
- }
代码2(inszva代码)
先判完不合法的情形
注意到d是一个奇数,所以可以起到对某一位赋1的作用,
从低位到高位考虑最后30位,低位已经为1了,高位的相加就不会影响低位
每次加上的都是d的倍数,最终答案一定是d的倍数,
这样还能保证二进制最后30位全是1
- #include
- using namespace std;
- typedef long long ll;
- int t;
- ll a,b,d,v;
- int main(){
- cin>>t;
- while(t--){
- cin>>a>>b>>d;
- int c=0;
- while(a%2==0 && b%2==0 && d%2==0){
- a/=2,b/=2,d/=2;
- c++;
- }
- if(d%2==0){
- cout<<-1<
- continue;
- }
- ll x=0;
- for(int i=0;i<30;++i){
- int bit=x>>i&1;
- if(!bit){
- x+=d<//d奇数 必能使第i位为1
- }
- }
- cout<<(x<
- }
- return 0;
- }
-
相关阅读:
什么?WPF 不支持 SVG ?
python web 开发与 Node.js + Express 创建web服务器入门
mysql redo 日志 、 undo 日志 、binlog
文件打包下载excel导出和word导出
面试:事件拦截相关问题
次时代摸鱼骚操作:人在办公室轻松观看家里电脑上的4k电影(移动端公网访问本地群辉存储视频文件)
STM32的IAP讲解
Axure RP PC电商平台Web端交互原型模板
XSS靶场prompt.ml过关详解
vue3+ts+element 前端实现分页
-
原文地址:https://blog.csdn.net/Code92007/article/details/127835565