Lamps (Codeforces 1839B)
Tags: Greedy, sortings

You have $$$n$$$ lamps, numbered by integers from $$$1$$$ to $$$n$$$. Each lamp $$$i$$$ has two integer parameters $$$a_i$$$ and $$$b_i$$$.At each moment each lamp is in one of three states: it may be turned on, turned off, or broken.Initially all lamps are turned off. In one operation you can select one lamp that is turned off and turn it on (you can't turn on broken lamps). You receive $$$b_i$$$ points for turning lamp $$$i$$$ on. The following happens after each performed operation:   Let's denote the number of lamps that are turned on as $$$x$$$ (broken lamps do not count). All lamps $$$i$$$ such that $$$a_i \le x$$$ simultaneously break, whether they were turned on or off. Please note that broken lamps never count as turned on and that after a turned on lamp breaks, you still keep points received for turning it on.You can perform an arbitrary number of operations.Find the maximum number of points you can get.

Input: The first line contains a single integer $$$t$$$ ($$$1 \le t \le 10^4$$$) — the number of test cases.The first line contains a single integer $$$n$$$ ($$$1 \le n \le 2 \cdot 10^5$$$) — the number of lamps.Each of the next $$$n$$$ lines contains two integers $$$a_i$$$ and $$$b_i$$$ ($$$1 \le a_i \le n, 1 \le b_i \le 10^9$$$) — parameters of the $$$i$$$-th lamp.It is guaranteed that sum of $$$n$$$ over all test cases doesn't exceed $$$2 \cdot 10^5$$$.

Output: For each test case, output one integer — the maximum number of points you can get.

Note: In first test case $$$n = 4$$$. One of ways to get the maximum number of points is as follows:   You turn lamp $$$4$$$ on and receive $$$b_4 = 13$$$ points.  The number of lamps that are turned on is $$$1$$$, so all lamps with $$$a_i \le 1$$$ (namely lamps $$$2$$$, $$$3$$$ and $$$4$$$) break. Lamp $$$4$$$ is no longer turned on, so the number of lamps that are turned becomes $$$0$$$.  The only lamp you can turn on is lamp $$$1$$$, as all other lamps are broken. You receive $$$b_1 = 2$$$ points for turning it on.  The number of lamps that are turned on is $$$1$$$. As $$$a_1 = 2$$$, lamp $$$1$$$ doesn't break. Your receive $$$13 + 2 = 15$$$ points in total. It can be shown that this is the maximum number of points you can get, so the answer for the first test case is $$$15$$$.In the second test case, one of the ways to get the maximum number of points is as follows:  On the first operation you turn on lamp $$$4$$$ and receive $$$2$$$ points. No lamps break after the first operation.  On the second operation you turn on lamp $$$3$$$ and receive $$$5$$$ points. After the second operation, there are $$$2$$$ lamps turned on. As $$$a_3 \le 2$$$, lamp $$$3$$$ breaks.  On the third operation, you turn on lamp $$$1$$$ and receive $$$4$$$ points.  On the fourth operation, you turn on lamp $$$5$$$ and receive $$$3$$$ points. After that there are $$$3$$$ lamps turned on: lamps $$$1$$$, $$$4$$$ and $$$5$$$. Lamps $$$1$$$, $$$2$$$, $$$4$$$ and $$$5$$$ simultaneously break, because for all of them $$$a_i \le 3$$$. You receive $$$2 + 5 + 4 + 3 = 14$$$ points in total. It can be shown that this is the maximum number of points you can get.In the third test case, one of the ways to get the maximum number of points is as follows:  Turn the lamp $$$3$$$ on and receive $$$4$$$ points. Lamps $$$1$$$ and $$$3$$$ break.  Turn the lamp $$$2$$$ on and receive $$$4$$$ points.  Turn the lamp $$$6$$$ on and receive $$$3$$$ points. Lamp $$$6$$$ breaks.  Turn the lamp $$$4$$$ on and receive $$$4$$$ points.  Turn the lamp $$$5$$$ on and receive $$$5$$$ points. Lamps $$$2$$$, $$$4$$$ and $$$5$$$ break. You receive $$$4 + 4 + 3 + 4 + 5 = 20$$$ points in total. It can be shown that this is the maximum number of points you can get.

Sample Inputs:
4
4
2 2
1 6
1 10
1 13
5
3 4
3 1
2 5
3 2
3 3
6
1 2
3 4
1 4
3 4
3 5
2 3
1
1 1

Sample Outputs:
15
14
20
1

Solution (Python):
import sys
import math
from collections import defaultdict

def get_ints():
    return map(int, sys.stdin.readline().strip().split())

def get_ls():
    return list(map(int, sys.stdin.readline().strip().split()))

def yesno(ok):
    print('YES' if ok else 'NO')
MOD = 1000000007

def main():
    for _ in range(int(input())):
        n = int(input())
        d = defaultdict(list)
        for i in range(n):
            (a, b) = get_ints()
            d[a].append(b)
        ans = 0
        for (k, v) in d.items():
            v.sort(reverse=True)
            ans += sum(v[:k])
        print(ans)
if __name__ == '__main__':
    main()

Solution (Python):
from sys import stdin
from math import ceil
from collections import defaultdict
_ = next(stdin)
for input in stdin:
    n = int(input)
    d = defaultdict(list)
    for i in range(n):
        line = next(stdin)
        (x, y) = [int(x) for x in line.split()]
        d[x].append(y)
    ans = 0
    for a in d:
        d[a].sort(reverse=True)
        ans += sum(d[a][:a])
    print(ans)

Solution (Python):
import sys, math
input = sys.stdin.readline
for iii in range(int(input())):
    g = int(input())
    f = {}
    for ir in range(g):
        (a, b) = [int(t) for t in input().split()]
        if f.get(a):
            f[a].append(b)
        else:
            f[a] = [b]
    ss = 0
    for i in f:
        f[i].sort(reverse=True)
        ss += sum(f[i][:i])
    print(ss)