Search in Parallel (Codeforces 1814C)
Tags: Greedy, sortings

Suppose you have $$$n$$$ boxes. The $$$i$$$-th box contains infinitely many balls of color $$$i$$$. Sometimes you need to get a ball with some specific color; but you're too lazy to do it yourself.You have bought two robots to retrieve the balls for you. Now you have to program them. In order to program the robots, you have to construct two lists $$$[a_1, a_2, \dots, a_k]$$$ and $$$[b_1, b_2, \dots, b_{n-k}]$$$, where the list $$$a$$$ represents the boxes assigned to the first robot, and the list $$$b$$$ represents the boxes assigned to the second robot. Every integer from $$$1$$$ to $$$n$$$ must be present in exactly one of these lists.When you request a ball with color $$$x$$$, the robots work as follows. Each robot looks through the boxes that were assigned to that robot, in the order they appear in the list. The first robot spends $$$s_1$$$ seconds analyzing the contents of a box; the second robot spends $$$s_2$$$. As soon as one of the robots finds the box with balls of color $$$x$$$ (and analyzes its contents), the search ends. The search time is the number of seconds from the beginning of the search until one of the robots finishes analyzing the contents of the $$$x$$$-th box. If a robot analyzes the contents of all boxes assigned to it, it stops searching.For example, suppose $$$s_1 = 2$$$, $$$s_2 = 3$$$, $$$a = [4, 1, 5, 3, 7]$$$, $$$b = [2, 6]$$$. If you request a ball with color $$$3$$$, the following happens:  initially, the first robot starts analyzing the box $$$4$$$, and the second robot starts analyzing the box $$$2$$$;  at the end of the $$$2$$$-nd second, the first robot finishes analyzing the box $$$4$$$. It is not the box you need, so the robot continues with the box $$$1$$$;  at the end of the $$$3$$$-rd second, the second robot finishes analyzing the box $$$2$$$. It is not the box you need, so the robot continues with the box $$$6$$$;  at the end of the $$$4$$$-th second, the first robot finishes analyzing the box $$$1$$$. It is not the box you need, so the robot continues with the box $$$5$$$;  at the end of the $$$6$$$-th second, the first robot finishes analyzing the box $$$5$$$. It is not the box you need, so the robot continues with the box $$$3$$$. At the same time, the second robot finishes analyzing the box $$$6$$$. It is not the box you need, and the second robot has analyzed all the boxes in its list, so that robot stops searching;  at the end of the $$$8$$$-th second, the first robot finishes analyzing the box $$$3$$$. It is the box you need, so the search ends;  so, the search time is $$$8$$$ seconds. You know that you are going to request a ball of color $$$1$$$ $$$r_1$$$ times, a ball of color $$$2$$$ $$$r_2$$$ times, and so on. You want to construct the lists $$$a$$$ and $$$b$$$ for the robots in such a way that the total search time over all requests is the minimum possible.

Input: The first line contains one integer $$$t$$$ ($$$1 \le t \le 10^4$$$) — the number of test cases.Each test case consists of two lines:   the first line contains three integers $$$n$$$, $$$s_1$$$, $$$s_2$$$ ($$$2 \le n \le 2 \cdot 10^5$$$; $$$1 \le s_1, s_2 \le 10$$$);  the second line contains $$$n$$$ integers $$$r_1, r_2, \dots, r_n$$$ ($$$1 \le r_i \le 10^6$$$). Additional constraint on the input: the sum of $$$n$$$ over all test cases does not exceed $$$2 \cdot 10^5$$$.

Output: For each test case, print two lines. The first line should contain the list $$$a$$$, the second line — the list $$$b$$$. Each list has to be printed as follows: first, print the number of elements in it, and then the elements themselves.If there are multiple answers, you may print any of them.


Sample Inputs:
3
7 3 1
8 6 4 4 4 1 7
5 1 10
1 1 1 1 1
8 1 1
4 5 6 8 1 7 3 2

Sample Outputs:
2 5 6
5 1 7 2 4 3
5 4 3 5 2 1
0
4 4 2 7 5
4 6 3 1 8

Solution (Python):
import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
from math import isqrt
for _ in range(int(input())):
    (n, s1, s2) = map(int, input().split())
    r = input().split()
    t = 1
    l = []
    for x in r:
        l.append((int(x), t))
        t += 1
    l.sort(key=lambda x: x[0])
    lens1 = 0
    lens2 = 0
    ls1 = ''
    ls2 = ''
    for x in range(n - 1, -1, -1):
        t1 = (lens1 + 1) * s1
        t2 = (lens2 + 1) * s2
        if t1 < t2:
            lens1 += 1
            ls1 += str(l[x][1]) + ' '
        else:
            lens2 += 1
            ls2 += str(l[x][1]) + ' '
    print(str(lens1) + ' ' + ls1)
    print(str(lens2) + ' ' + ls2)

Solution (Python):
def problem():
    (n, s1, s2) = [int(_) for _ in input().split()]
    required = [int(_) for _ in input().split()]
    box_order = sorted(range(1, n + 1), key=lambda x: required[x - 1], reverse=True)
    robot1 = []
    robot2 = []
    timer1 = s1
    timer2 = s2
    for box in box_order:
        if timer1 < timer2:
            robot1.append(box)
            timer1 += s1
        else:
            robot2.append(box)
            timer2 += s2
    print(' '.join([str(_) for _ in [len(robot1)] + robot1]))
    print(' '.join([str(_) for _ in [len(robot2)] + robot2]))
t = int(input())
for _ in range(t):
    problem()

Solution (Python):
def write_list(l):
    return f'{len(l)} ' + ' '.join((str(k) for k in l))

def do_everything():
    num_cases = int(input())
    while True:
        try:
            [_, s1, s2] = [int(s) for s in input().split(' ')]
            R = [int(s) for s in input().split(' ')]
            (s1_list, s2_list) = stuff(R, s1, s2)
            print(write_list(s1_list))
            print(write_list(s2_list))
        except:
            return

def stuff(R, s1, s2):
    R_ord = sorted(enumerate(R), key=lambda p: p[1], reverse=True)
    s1_list = []
    s2_list = []
    for (i, r) in R_ord:
        num_steps_s1 = r * (len(s1_list) + 1) * s1
        num_steps_s2 = r * (len(s2_list) + 1) * s2
        if num_steps_s1 < num_steps_s2:
            s1_list.append(i + 1)
        else:
            s2_list.append(i + 1)
    return (s1_list, s2_list)
do_everything()