Codeforces Round #608 (Div. 2)E(二分,思维,树的建立)
作者:互联网
画出来是一个树的结构,数值x越小,它在1~n中出现的次数就越多(满足单调性,二分解决),次数=以它为根节点的树的大小;
子树奇偶有序1>3>5>7,但是3和4大小不能确定,所以必须奇偶二分;
链之间的关系(l*2,r*2+1)(每一层)
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll n,k; bool check(ll x)//找x出现的次数 { ll l=x,r=x; if(!(x&1)) r++; ll ans=0; while(l<=n) { ans+=min(n,r)-l+1; l<<=1; r<<=1; r++; } return ans>=k; } int main() { cin>>n>>k; ll l=1,r=(n+1)/2; ll ans=0; while(l<=r) {///二分枚举合法奇数枝条 (最右边开始) ll midd=(l+r)>>1; //cout<<"midd = "<<midd<<endl; if(check(2*midd-1)) l=midd+1,ans=2*midd-1; else r=midd-1; //cout<<"l = "<<l<<"r = "<<r<<"ans ="<<ans<<endl; } l=1,r=n/2; while(l<=r) {///偶数枝条(最左边开始) ll midd=(l+r)>>1; //cout<<"midd = "<<midd<<endl; if(check(2*midd)) l=midd+1,ans=max(2*midd,ans);//两者取大者 else r=midd-1; //cout<<"l = "<<l<<"r = "<<r<<"ans ="<<ans<<endl; } cout<<ans<<endl; return 0;}
标签:二分,奇偶,cout,ll,608,long,Codeforces,ans,Div 来源: https://www.cnblogs.com/sweetlittlebaby/p/12640034.html