Project Euler 186
Project Euler 186
题目
Connectedness of a network
Here are the records from a busy telephone system with one million users:
| Rec Nr | Caller | Called |
|---|---|---|
| $1$ | $200007$ | $100053$ |
| $2$ | $600183$ | $500439$ |
| $3$ | $600863$ | $701497$ |
| $\dots$ | $\dots$ | $\dots$ |
The telephone number of the caller and the called number in record $n$ are $\text{Caller}(n) = S{2n-1}$ and $\text{Called}(n) = S{2n}$ where $S_{1,2,3,\dots}$ come from the “Lagged Fibonacci Generator”:
For $1 \le k \le 55, S_k = [100003 - 200003k + 300007 k^3] (\text{modulo\ } 1000000)$
For $56 \le k, S_k = [S_k-24 + S_k-55] (\text{modulo\ } 1000000)$
If $\text{Caller(n)} = \text{Called(n)}$ then the user is assumed to have misdialled and the call fails; otherwise the call is successful.
From the start of the records, we say that any pair of users $X$ and $Y$ are friends if $X$ calls $Y$ or vice-versa. Similarly, $X$ is a friend of a friend of $Z$ if $X$ is a friend of $Y$ and $Y$ is a friend of $Z$; and so on for longer chains.
The Prime Minister’s phone number is $524287$. After how many successful calls, not counting misdials, will $99\%$ of the users (including the PM) be a friend, or a friend of a friend etc., of the Prime Minister?
并查集
并查集:用于高效处理一些不相交集合的数据结构。一般有两个操作:合并两个集合;查询两个元素是否在同一个集合中。
可以通过优化将并查集这两种单次操作优化到$O(\alpha(n))$级别,其中$\alpha(n)$是反阿克曼函数(一个增长速率非常接近于零的函数)。
解决方案
本题为并查集的模板题,直接用并查集数据结构实现。
代码中需要维护每个集合的大小。为了避免错误,只有两个元素不属于同一个集合时才需要合并。
代码
1 |
|