我们观察到,如果奇数,只能由*2转移来,如果是偶数可以从x+1和x*2两种情况转移而来
因此我们通过式子画出集合,观察到我们应该奇偶判断,首先我们观察到画出树形结构后分别对于奇偶,存在单调性,因此可以二分
对于check,我们发现通过二进制的转换后,*2相当于右移1,*2+1相当于右移1后+1,因此其实就看后面有多少位。只要比较次方和n-x+1的大小就行.
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=3e5+10; ll n,k; ll check(ll x){ ll t=1,ans=0; while(x<=n){ ans+=min(t,n-x+1); x<<=1; t<<=1; } return ans; } int main(){ ios::sync_with_stdio(false); cin>>n>>k; int i; ll ans=0; ll l=1,r=n/2; while(l<r){ ll mid=l+r+1>>1; if(check(2*mid)+check(2*mid+1)>=k){ ans=max(ans,mid*2); l=mid; } else r=mid-1; } if(check(2*l)+check(2*l+1)>=k) ans=max(ans,l*2); l=1,r=(n+1)/2; while(l<r){ ll mid=l+r+1>>1; if(check(2*mid-1)>=k){ ans=max(ans,mid*2-1); l=mid; } else r=mid-1; } if(check(2*l-1)>=k) ans=max(ans,2*l-1); cout<<ans<<endl; }