Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* the number of ones between n+1 to 2n increases with n...so given a certain number m we can find which n and 2n have m numbers with exactly k digits one by binary search and digit dp */
- /*********************** let the play begin() ***********************************/
- vl v1,v2;ll dp[70][2][2][70],m,k;int lim;
- ll giveres(int pos,int low,int high,ll pk)
- {
- if(pk>k)return 0ll;
- if(pos==lim)
- {
- if(pk==k)return 1ll;
- return 0ll;
- }
- ll &ret = dp[pos][low][high][pk];
- if(ret!=-1)return ret;
- ret = 0;
- int h = 1,l = 0;
- if(high)h = v2[pos];
- if(low)l = v1[pos];
- for(int i = l;i<=h;i++)
- {
- ret+=giveres(pos+1,low&(i==l),high&(i==h),pk+i);
- }
- return ret;
- }
- int main()
- {
- booster()
- ///read("input.txt");
- cin>>m>>k;
- ll low = 1,high = 1e18,mid;
- ll ans = -1;
- while(low<=high)
- {
- mid = (low+high)>>1;
- ll x = mid;v1.clear();v2.clear();
- ll y = 2*x;
- x++;
- while(x)
- {
- v1.pb(x%2);
- x/=2;
- }
- while(y)
- {
- v2.pb(y%2);
- y/=2;
- }
- while(v1.size()<v2.size())v1.pb(0);
- reverse(all(v1));
- reverse(all(v2));
- lim = v1.size();
- mem(dp,-1);
- if(giveres(0,1,1,0)>=m)
- {
- ans = mid;
- high = mid - 1;
- }
- else low = mid + 1;
- ///cout<<mid<<" "<<2*mid<<" "<<giveres(0,1,1,0)<<endl;
- }
- cout<<ans;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement