CF1271E Common Number(二分+思维)

我们观察到,如果奇数,只能由*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;
}
View Code
没有人不辛苦,只有人不喊疼
原文地址:https://www.cnblogs.com/ctyakwf/p/13687983.html