Codeforces Round #843 (Div. 2) C Interesting Sequence

文章讨论了一种针对大整数n和x的算法问题,通过位操作和二分查找在O(logn)的时间复杂度内找到最小的m值。当n和x的特定位不匹配时,算法会更新边界并最终确定m。如果无法找到解决方案,则输出-1。

Problem - C - Codeforces

题意:

给定n和x,求最小的m使得:

n和x范围是1e18

思路:

看到1e18,要不就是打表找规律,要不就是O(1),要不就是O(logn)

因为这题是bitmask,因此按位考虑,是O(logn)的

让我们凭空求m,要不枚举,要不二分,要不直接求

枚举肯定不行

二分的话不能维护区间与的结果

因此我们根据n和x的位表示直接求m

Code:

#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,x;
void solve(){
    cin>>n>>x;
    bitset<64> b1(n),b2(x);
    int l=n,r=5e18;
    for(int i=63;i>=0;i--){
        if(b1[i]==0&&b2[i]==0) continue;
        else if(b1[i]==0&&b2[i]==1){
            cout<<-1<<'\n';
            return;
        }else if(b1[i]==1&&b2[i]==1){
            r=min(r,(n/(1ll<<i)+1)*(1ll<<i)-1);
        }else{
            l=max(l,(n/(1ll<<i)+1)*(1ll<<i));
        }
    }
    if(l<=r) cout<<l<<'\n';
    else cout<<-1<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int __=1;cin>>__;
    while(__--)solve();return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值