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 |
|