



Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Main points of this past exam are: Theoretical Algorithms, Number Theoretical, Asymptotic Upper, Upper Bound, Encoding, Algorithm Design, Sorted Arrays, Fft Matrix, Depth Rst Search, Starting Point
Typology: Exams
1 / 7
This page cannot be seen from the preview
Don't miss anything!




2 1 ·^
2 2 ·^...^ ·^
2 n ≤^2 ·^ nlim→∞
2 n = 0.
√n = Θ(
n). False: 3log^2
√n = 3(^ (^12) log 2 n) = n(^ (^12) log 2 3) = (
n)log^2 .
If f (n) = O(g(n)), then g(n) = Ω(f (n)). True: By definition of Ω (this is in fact how your textbook defines Ω).
∑n j=1 j^ =^ O(n^ log^ n). False:
∑n j=1 j^ =^
1 2 n(n^ + 1) = Θ(n
The number of bits in an integer x is Θ(log x). Therefore, the number of bits in ab^ is Θ(log(ab)) = Θ(b log a). Now log a = O(n) and b = O(2n) since both a and b are n-bit numbers, so b log a = O(n · 2 n). Thus, O(n · 2 n) is an upper bound on the number of bits in ab. Similarly, the number of bits in ab
c is Θ(log(a(b
c) )) = Θ(bc^ log a). Again, log a = O(n), b = O(2n), and c = O(2n) since a, b, and c are n-bit numbers, so bc^ log a = O(n · (2n)(
n) ) = O(n · 2 (n·^2
n) ). Thus, O(n · 2 (n·^2
n) ) is an upper bound on the number of bits in ab c .
(a) The secret key d equals e−^1 mod (p − 1)(q − 1). Since the n-bit primes p and q are given as input, d can be found in O(n^3 ) time using the extended Euclid’s algorithm.
(b) The ciphertext c equals me^ mod pq. Therefore, c can be computed in O(n^2 log e) time using the repeated squaring method for modular expo- nentiation.
First off, o(kl) means asymptotically faster than O(kl). This threw most people off, and we gave no credit for Ω(kl) solutions since they were trivial.
number of each DFS run. If there exists a pair of nodes u and v, satisfying pre(v) < pre(u) < post(u) < post(v) for one DFS run and pre(u) < pre(v) < post(v) < post(u) for another DFS run, then u and v are on a cycle. If there doesn’t exist such a pair of nodes, then output “No two nodes are on a cycle”.
pre(u) < post(u) < pre(v) < post(v). Suppose v is explored before u. Since u is reachable from v and this is a directed graph, we must have pre(v) < pre(u) < post(u) < post(v), contradicting the assumption that the intervals are disjoint. Therefore, u must be explored before v giving pre(u) < post(u) < pre(v) < post(v). It should also be pointed out that in case of an undirected graph, both pre(u) < post(u) < pre(v) < post(v) and pre(v) < post(v) < pre(u) < post(u) are possible. However, we gave full credit if you only answered the directed graph case.
In the case of a connected graph, pre(s) = 1 and post(s) = 2|V |, where |V | is the total number of nodes in the graph. In the case of an unconnected graph, pre(s) = 1 and post(s) = 2|C| < 2 |V |, where |C| is the number of nodes of the connected component containing the starting point s (i.e. the number of the nodes reachable from the starting point, including the starting point itself).
Start from any node and run Dijkstra’s algorithm. Then k + 1 times, do the following: update all the negative edges (not strictly necessary but easier to prove correctness), place everything back in the priority queue, and run the loop of Dijkstra’s that pulls nodes out and updates the adjacent edges. The graph has a negative cycle if and only if any dist(v) changes in the last iteration (i.e. the k + 1 iteration). The top level algorithm NegativeCycle, which uses subroutines DijkstraLoop and UpdateNegativeEdges, is given below.
Algorithm 1: NegativeCycle Input: Input graph G Output: True if G contains a negative cycle, False otherwise 1 s = any vertex ∈ V ; 2 for all u ∈ V do 3 dist(u) = ∞; 4 end 5 dist(s) = 0; 6 Q = makequeue(V, dist); 7 DijkstraLoop(G, Q); 8 for i = 1 to k do 9 U pdateN egativeEdges(G, dist); 10 Q = makequeue(V, dist); 11 DijkstraLoop(G, dist, Q); 12 end 13 if U pdateN egativeEdges(G, dist) then 14 return True 15 else 16 Q = makequeue(V, dist); 17 return DijkstraLoop(G, dist, Q) 18
Algorithm 2: DijkstraLoop Input: Input graph G, array of dist values dist, priority queue Q Output: True if any dist value is updated, False otherwise 1 retV alue = F alse; 2 while Q is not empty do 3 u = deletemin(H); 4 for all edges (u, v) ∈ E do 5 if dist(v) > dist(u) + l(u, v) then 6 dist(v) = dist(u) + l(u, v); 7 decreasekey(H, v); 8 retV alue = T rue; 9 10 end 11 end 12 return retValue
For the runtime, we have Θ(k) iterations of Dijkstra’s algorithm (which each take O(m + n log n) time using a Fibonacci heap to implement the priority queue) and Θ(k) updates of the negative edges (which each take O(m) time). So the total running time is O(k(m + n log n)).
Remove all the negative edges. Find a single source shortest path from each endpoint of a negative edge to each other endpoint (using Dijkstra’s algorithm). Construct a graph on the (at most) 2k nodes with edge distances that correspond to the shortest path distances between the corresponding point in the positive edge graph. Put in the negative edges between the original nodes. This is a graph on 2k nodes with O(k^2 ) edges. One can check for a negative cycle in the is graph in time O(k^3 ). Any negative cycle in the new graph corresponds to a negative cycle in the original since any edge in this graph corresponds to a path in the original graph. Moreover, any negative cycle C in the original graph must contain one or more negative edges (denote the set of negative edges by N ). Suppose C does not consist of positive edge shortest paths between endpoints of negative edges. Then the cycle C′^ formed by connecting the endpoints of N using positive edges shortest paths has weight less than C. Thus, C′^ is a negative cycle. This shows that if there is a negative cycle C in the original graph, then there is a negative cycle consisting of positive edge shortest paths between endpoints of negative edges, i.e. a negative cycle in the new graph. Thus, our algorithm finds a negative cycle if and only if a negative cycle existed in the original graph. We have Θ(k) iterations of Dijkstra’s algorithm following by performing Bellman-Ford on graph with Θ(k) nodes and Θ(k^2 ) edges. Thus, the running time for this is O(k(m + n log n) + k^3 ) by implementing the priority queue with a Fibonacci heap.