Keshi Is Throwing a Party (Codeforces 1610C)
Tags: Greedy, binary search

Keshi is throwing a party and he wants everybody in the party to be happy.He has $$$n$$$ friends. His $$$i$$$-th friend has $$$i$$$ dollars. If you invite the $$$i$$$-th friend to the party, he will be happy only if at most $$$a_i$$$ people in the party are strictly richer than him and at most $$$b_i$$$ people are strictly poorer than him.Keshi wants to invite as many people as possible. Find the maximum number of people he can invite to the party so that every invited person would be happy.

Input: The first line contains a single integer $$$t$$$ $$$(1\le t\le 10^4)$$$ — the number of test cases. The description of the test cases follows.The first line of each test case contains a single integer $$$n$$$ $$$(1\le n\le 2 \cdot 10^5)$$$ — the number of Keshi's friends.The $$$i$$$-th of the following $$$n$$$ lines contains two integers $$$a_i$$$ and $$$b_i$$$ $$$(0 \le a_i, b_i < n)$$$.It is guaranteed that the sum of $$$n$$$ over all test cases doesn't exceed $$$2 \cdot 10^5$$$.

Output: For each test case print the maximum number of people Keshi can invite.

Note: In the first test case, he invites the first and the second person. If he invites all of them, the third person won't be happy because there will be more than $$$1$$$ person poorer than him.

Sample Inputs:
3
3
1 2
2 1
1 1
2
0 0
0 1
2
1 0
0 1

Sample Outputs:
2
1
2

Solution (Python):
def solve():
    n = int(input())
    a = [0] * (n + 1)
    b = [0] * (n + 1)
    for i in range(1, n + 1):
        (a[i], b[i]) = map(int, input().split())
    (left, right) = (1, n + 1)
    ans = 1
    while left <= right:
        mid = (left + right) // 2
        take = 0
        for i in range(1, n + 1):
            if b[i] >= take and a[i] >= mid - take - 1:
                take += 1
            if mid == take:
                break
        if take == mid:
            ans = mid
            left = mid + 1
        else:
            right = mid - 1
    print(ans)
t = int(input())
for _ in range(t):
    solve()

Solution (Python):
def isPossibletoInvite(MID, arrayA, arrayB, N):
    (count, upper, lower) = (0, MID - 1, 0)
    for i in range(N):
        if arrayA[i] >= upper and arrayB[i] >= lower:
            upper -= 1
            lower += 1
            count += 1
        if count == MID:
            return True
    return False
q = int(input())
for _ in range(q):
    n = int(input())
    a = []
    b = []
    for _ in range(n):
        (ai, bi) = map(int, input().split())
        a.append(ai)
        b.append(bi)
    (low, high, ans) = (1, n, 0)
    while low <= high:
        mid = (low + high) // 2
        if isPossibletoInvite(mid, a, b, n):
            ans = mid
            low = mid + 1
        else:
            high = mid - 1
    print(ans)

Solution (Python):
T = int(input())

def check(x, a, b, n):
    cnt = 0
    for i in range(1, n + 1):
        if a[i] >= x - cnt - 1 and b[i] >= cnt:
            cnt += 1
        if cnt >= x:
            return True
    return False
for _ in range(T):
    ans = 0
    n = int(input())
    a = [0] * (n + 1)
    b = [0] * (n + 1)
    for i in range(1, n + 1):
        (a[i], b[i]) = map(int, input().split())
    l = 1
    r = n
    while l <= r:
        mid = (l + r) // 2
        if check(mid, a, b, n):
            l = mid + 1
            ans = mid
        else:
            r = mid - 1
    print(ans)