Common Number
参考:Codeforces Round #608 (Div. 2) E - Common Number (二分 思维 树结构)
具体做法可详见参考博客。
关键在于在分了奇偶之后,就是有序的了
在数据范围很大的时候,要尝试降低其复杂度,对答案进行二分就是一种降低复杂度的办法,把复杂度降到了O(log(n))的级别,这样即使是1e18的数据也能够跑完。
代码:
// Created by CAD on 2020/1/2.
#include <bits/stdc++.h>
#define fi first
#define se second
#define pll pair<long long,long long>
#define ll long long
using namespace std;
ll n,k;
bool judge(ll x)
{
queue<pll> q;
ll cnt=0;
if(x&1) q.push({x,x});
else q.push({x,x+1});
while(q.size())
{
auto i=q.front(); q.pop();
cnt+=min(n,i.se)-i.fi+1;
if((i.fi<<1)<=n) q.push({i.fi<<1,i.se<<1|1});
}
return cnt>=k;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>k;
ll ans=-1;
//遍历偶数
ll l=1,r=n/2;
while(l<=r)
{
ll mid=(l+r)>>1;
if(judge(mid<<1)) ans=max(ans,mid<<1),l=mid+1;
else r=mid-1;
}
//遍历奇数
l=0,r=n/2;
while(l<=r)
{
ll mid=(l+r)>>1;
if(judge(mid<<1|1)) ans=max(ans,mid<<1|1),l=mid+1;
else r=mid-1;
}
cout<<ans<<endl;
return 0;
}