1. 程式人生 > 實用技巧 >CF1271E Common Number(二分+思維)

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