http://community.topcoder.com/stat?c=problem_statement&pm=13765
Problem Statement
Bob is going to create a graph with N nodes. The graph will be constructed in two steps. First, Bob will take N isolated vertices, label them 1 through N and color each of them using one of K colors. Then, Bob will add some directed edges to the graph. For each i between 2 and N, inclusive, Bob may choose a single value j < i such that the nodes i and j have different colors. If he does, he will add the edge from i to j to his graph. Note that Bob may choose not to add any edge from node i, even if there are some valid choices of j.
Two graphs are considered the same if they have the same node colors and the same set of edges.
You are given the longs N and K. You are also given an int M. Compute and return the number of different graphs Bob may construct, modulo M.
Definition
- ClassColorfulLineGraphs
- MethodcountWays
- Parameterslong long , long long , int
- Returnsint
- Method signatureint countWays(long long N, long long K, int M)
Limits
- Time limit (s)2.000
- Memory limit (MB)256
Constraints
- N will be between 1 and 1,000,000,000,000 (10^12), inclusive.
- K will be between 1 and 1,000,000,000,000 (10^12), inclusive.
- M will be between 2 and 1,000,000 (10^6), inclusive.
Test cases
-
- N3
- K2
- M100000
Returns24 -
- N15
- K3
- M1000000
Returns510625 -
- N100000
- K100000
- M999999
Returns185185 -
- N1000000000000
- K6
- M1000000
Returns109376 -
- N5000
- K1000000000000
-
M314159
-
Returns202996
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -
题解
-
The constraints, except for M are much larger than in the division 2 version. It is interesting M remains relatively small, as if O(M) or similar was intended. The large constraints for N and K suggest we might need to get creative, however.
Imagine we are deciding what to do for the nodes in order from left to right (lowest index to highest). Imagine we already made decisions for the first i nodes. We know their colors and we know which edges (or lack of) we picked for each of them. Remember (from division 2) that when assigning things to do with the higher nodes, we only need to remember the number of nodes of each color that have been assigned, we don't need to know the edges. Let's count the number of decisions for node # i:
- We may decide to use color #0. Then we have to pick an edges. We can pick no edge at all or we can connect node i to any node of a color different than 0. in which case we have 1+(i−count(i,0)) options, where count(i,0) is the number of nodes of color 0 among the first i nodes.
- For color 1: 1+i−count(i,1).
- ...
- For color + k−1: 1+i−count(i,k−1).
What happens if we add together all the options?
1+i−count(i,0)
+1+i−count(i,1)
+1+i−count(i,2)
+...
+1+i−count(i,k−1)
k times 1, k times i and the sum of all counts:
k+ki−∑j=0j<k(count(i,j))This is the interesting part: What is ∑j=0j<k(count(i,j)) ? The sum of all the counts of colors among the first i nodes. This will be always equal to i. There are i nodes in total and the sum of all counts for each color will always be i. This means that the number of options for node i is: k+ki−i=k+i(k−1). So in fact, the color choices before i are not relevant for the final result, only the total number of available colors. This way we can have an O(N) formula, just multiply k+i(k−1) for each i : ∏i=0i<N(i(k−1)+k)
N is still too large even for an O(N) so we need more improvements. This is where the small constraints on M can come into play. From i=0, to N−1, the value imodM behaves in a cycle. So imagine M=3. For i=0,1,2,3,4,5,6,7, the values of imod3 will be: 0,1,2,0,1,2,0,1. Remember that (a⋅b)modM=((amodM)(bmodM))modM, so ∏i=0i<N(i(k−1)+k)modM is equal to: ∏i=0i<N((i(k−1)+k)modM). Each (i(k−1)+k)modM depends solely on i, more specifically imodM:
(i(k−1)+k)modM≡(((imodM)(k−1)modM)+(kmodM))The only non-constant part is imodM. This part is cyclic and repeats every M parts. So back to the N=7,M=3 example: i=0,i=3,i=6 all will yield the same value of (i(k−1)+k)modM. We can say the same about i=1,i=4 and i=2,i=5. We just need to use this cycle to our advantage.
So for simplicity, let's name g(i)=(i(k−1)+k)modM. We need to calculate:
(g(0)⋅g(1)⋅g(2)⋅...⋅g(N−1))modMWe have the knowledge that for every pair i≡jmodM, g(i)≡g(j)modM (The values of g(i) are repeated every M times). So imagine this:
(g(0)⋅g(1)⋅g(2)⋅...⋅g(M−1)⋅g(M)⋅g(M+1)⋅g(M+2)⋅...⋅g(2M−1)⋅...g((N/M)−1)
⋅g((N/M)⋅M)⋅g((N/M)⋅M+1)⋅...⋅g((N/M)⋅M+(NmodM)−1)modMWhat we have here is the same M values are repeated over and over again, the first M values, the next M values and so and so. They will be repeated (N/M) times (integer, round down division). There will be some extra values depending if M divides N evenly. NmodM additional values (The remainder).
(g(0)⋅g(1)⋅g(2)⋅...⋅g(M−1)⋅g(0)⋅g(1)⋅g(2)⋅...⋅g(M−1)⋅...g(0)⋅g(1)⋅g(2)⋅...⋅g(M−1)
⋅g(0)⋅g(1)⋅...⋅g((NmodM)−1)modMThe product g(0)⋅g(1)⋅g(2)⋅...⋅g(M−1) is repeated exactly N/M times. So we can actually calculate the product of the first (N/M)M values by using the following:
(g(0)⋅g(1)⋅g(2)⋅...⋅g(M−1))N/MThis requires O(M) time to calculate the product of the first M values, then we can use O(log(N/M)) time to calculate the power (for example, using exponentiation by squaring).
Finally we need to multiply that to: g(0)⋅g(1)⋅...⋅g((NmodM)−1), This requires O(M) further steps. In total we have an O(O(log(N/M))+M) algorithm:
long mod_pow(long x, long y, long M) { //exponentiation by squaring: long r = 1; long a = x; while (y > 0) { if (y % 2 == 1) { r = (r * a) % M; } a = (a * a) % M; y /= 2; } return r; } int countWays(long N, long K, int M) { long p = 1, q = 1; // p will store product of all i < M // q will store product of all i &ly; N%M for (int i = 0; i < M; i++) { long x = (i*(K - 1) + K) % M; p = (p * x) % M; if (i < N%M) { q = p; } } return (mod_pow(p, N/M, M) * q) % M; }
看完有没有很爽的感觉^-^ -


702

被折叠的 条评论
为什么被折叠?




The 24 different graphs are shown below. In each picture, the vertices have labels 1, 2, 3 from the left to the right.