Problem:

賞金 (Prize)

Segtree くんは、 $N$ 人のチームでプログラミングコンテストに出場し、 $K$ 円の賞金を得ました！今、この賞金を分配しようとしています。

Segtree くんを含む $N$ 人のチームメンバーそれぞれには、実力順に $1$ から $N$ までの番号がつけられています。Segtree くんは $1$ 番です。

$i$ 番のチームメイト $(i \geq 2)$ の得る賞金額が「$i - 1$ 番のチームメイトの得た賞金額の半分を整数に切り捨てた値」より少ないと、その人は怒ってしまいます。

怒る人が一人もいないように $K$ 円の賞金を分配するとき、Segtree くんがもらえる賞金の最大値を求めてください。

入力

入力は以下の形式で標準入力から与えられる。

N K

出力

Segtree くんがもらえる賞金の最大値を出力してください。

ただし、最後には改行を入れること。

制約

    
$1 \leq N,K \leq 10^{18}$

    
入力は全て整数である。

入力例1

1 1

出力例1

1

入力例2

819875141880895728 349993004923078537

出力例2

174996502461539284



Sample input:
1 1


Sample output:
1

Submission status: Accepted

Solution code:
n,k = map(int,input().split())

ok,ng = 0,k+1
while ng-ok>1:
    mid = (ng+ok)//2

    s = 0
    m = mid
    for i in range(n):
        s += m
        m //= 2
        if m == 0:
            break

    if s <= k:
        ok = mid
    else:
        ng = mid

print(ok)

Submission status: Accepted

Solution code:
from itertools import *
from bisect import *
from math import *
from collections import *
from heapq import *
from random import *
import sys

sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep="\n")
def II(): return int(sys.stdin.readline())
def MI(): return map(int, sys.stdin.readline().split())
def MI1(): return map(int1, sys.stdin.readline().split())
def MF(): return map(float, sys.stdin.readline().split())
def LI(): return list(map(int, sys.stdin.readline().split()))
def LI1(): return list(map(int1, sys.stdin.readline().split()))
def LF(): return list(map(float, sys.stdin.readline().split()))
def LLI(rows_number): return [LI() for _ in range(rows_number)]
dij = [(1, 0), (0, 1), (-1, 0), (0, -1)]

def main():
    def ok(m):
        s=0
        cnt=0
        while m:
            s+=m
            cnt+=1
            if s>k:return False
            if cnt==n:break
            m>>=1
        return True

    n,k=MI()
    l=0
    r=k+1
    while l+1<r:
        m=(l+r)//2
        if ok(m):l=m
        else:r=m
    print(l)

main()

Submission status: Accepted

Solution code:
N,K=map(int,input().split())
OK=0
NG=K+1

while NG-OK>1:
    #print(OK,NG)
    mid=(OK+NG)//2
    ANS=0
    money=mid

    for i in range(N):
        ANS+=money
        money//=2
        if money==0:
            break

    if ANS<=K:
        OK=mid
    else:
        NG=mid
print(OK)

Submission status: Accepted

Solution code:
n,k=map(int,input().split())
l,r=0,k+1
while r-l>1:
  m=(l+r)//2
  res = m
  t = m
  for i in range(n-1):
    t //= 2
    res += t
    if t == 0:
      break
  if res > k:
    r = m
  else:
    l = m
print(l)