随着过去十年单核处理器性能提升的停滞,许多 IT 公司在需要进行繁重计算时不得不采用多处理方法。
Yandex 就是这样一家公司,我们一直在不断发明尖端技术来解决多线程和多处理问题。作为这些技术的示例,我们想向您介绍我们针对多线程任务上下文切换的新方法。
更正式地说,我们考虑 $N$ 个线程,为简单起见,假设每个线程都是一个包含 $a_i$ 条原子指令的函数(执行一条原子指令需要一个时间片)。
在每个时间片,我们的调度程序执行以下步骤:
- 考虑所有尚未执行完毕的线程。
- 以相等的概率随机选择其中一个线程,并执行其恰好一条指令。
如果一个线程的所有指令都已执行完毕,则该线程被视为已执行。
在所有线程的所有指令执行完毕后,我们得到一个线程执行完毕的顺序。对于每个线程 $i$,我们对其在该列表中的期望位置 $e_i$ 感兴趣。
正式地,线程的期望位置计算如下。考虑线程执行完毕的所有不同顺序 $p_1, p_2, \dots, p_{N!}$ 以及这些顺序对应的概率 $r_1, r_2, \dots, r_{N!}$。线程 $i$ 在列表中的期望位置为:
$$\sum_{j=1}^{N!} p_j(i)r_j$$
其中 $p_j(i)$ 是线程 $i$ 在顺序 $j$ 中的位置。
输入格式
第一行包含线程数量 $N$ ($1 \le N \le 10^5$)。第二行包含 $N$ 个整数 $a_1, a_2, \dots, a_N$,用空格分隔 ($1 \le a_i \le 5000$)。
输出格式
输出 $N$ 行:第 $i$ 行必须包含值 $e_i$,要求绝对误差或相对误差不超过 $10^{-6}$。
样例
输入 1
2 1 5000
输出 1
1.0000000000 2.0000000000