cf1271E——数学找规律,二分套二分
作者:互联网
哎,规律就是难看出来
/* 二分判y是否可行,judge函数里: 找规律可以发现: y是奇数时 第0层:y 第一层:2y,2y+1 第二层:4y,4y+1,4y+2,4y+3 第三层:8y,8y+1,8y+2,8y+3,8y+4,8y+5,8y+6,8y+7 ... 第k层:[2^k*y,2^k*y+2^k-1] y是偶数时 第0层:y,y+1 第一层:2y,2y+1,2y+2,2y+3 第二层:4y,4y+1,4y+2,4y+3,4y+4,4y+5,4y+6,4y+7 第三层:8y,8y+1,8y+2,8y+3,8y+4,8y+5,8y+6,8y+7,8y+8,8y+9,8y+10,8y+11,8y+12,8y+13,8y+14,8y+15 ... 第k层:[2^k*y,2^k*y+2^(k+1)-1] 然后统计一下即可 特别注意,对起点是奇数偶数两种情况要特别注意一下,分开来进行二分 */ #include<bits/stdc++.h> using namespace std; #define ll long long ll n,K; ll Pow(ll a,ll b){ ll res=1; while(b){ if(b%2)res=res*a; b>>=1;a=a*a; } return res; } ll judge(ll y){ ll sum=0,k=0; if(y%2==0){//偶数 while(Pow(2,k)*y+Pow(2,k+1)-1<=n){ sum+=Pow(2,k+1); k++; } sum+=max(0ll,n-Pow(2,k)*y+1); } else { while(Pow(2,k)*y+Pow(2,k)-1<=n){ sum+=Pow(2,k); k++; } sum+=max(0ll,n-Pow(2,k)*y+1); } if(sum>=K)return 1; return 0; } int main(){ cin>>n>>K; ll L=0,R=(n-1)/2,mid,ans1=1; while(L<=R){ mid=L+R>>1; if(judge(mid*2+1)) ans1=mid*2+1,L=mid+1; else R=mid-1; } L=1,R=n/2; ll ans2=1; while(L<=R){ mid=L+R>>1; if(judge(mid*2)) ans2=mid*2,L=mid+1; else R=mid-1; } cout<<max(ans1,ans2)<<'\n'; }
标签:二分,4y,res,ll,mid,2y,8y,数学,cf1271E 来源: https://www.cnblogs.com/zsben991126/p/12115002.html