0% found this document useful (0 votes)
2 views

Competitive Programming 2 2nd Steven Halim download

The document provides information about the book 'Competitive Programming 2' by Steven Halim, including links to download it and other related competitive programming books. It outlines the contents of the book, which covers various topics such as problem-solving paradigms, data structures, and algorithms. Additionally, it offers tips for becoming competitive in programming contests.

Uploaded by

wanuzatrold
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Competitive Programming 2 2nd Steven Halim download

The document provides information about the book 'Competitive Programming 2' by Steven Halim, including links to download it and other related competitive programming books. It outlines the contents of the book, which covers various topics such as problem-solving paradigms, data structures, and algorithms. Additionally, it offers tips for becoming competitive in programming contests.

Uploaded by

wanuzatrold
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 81

Competitive Programming 2 2nd Steven Halim

download

https://ebookbell.com/product/competitive-programming-2-2nd-
steven-halim-4723160

Explore and download more ebooks at ebookbell.com


Here are some recommended products that we believe you will be
interested in. You can click the link to download.

Competitive Programming 4 Book 2 4th Steven Halim Felix Halim

https://ebookbell.com/product/competitive-programming-4-book-2-4th-
steven-halim-felix-halim-46668794

Competitive Programming 4 Book 2 4th Edition Steven Halim Felix Halim

https://ebookbell.com/product/competitive-programming-4-book-2-4th-
edition-steven-halim-felix-halim-46829310

Competitive Programming 4 The Lower Bound Of Programming Contests In


The 2020s 4th Edition Steven Halim

https://ebookbell.com/product/competitive-programming-4-the-lower-
bound-of-programming-contests-in-the-2020s-4th-edition-steven-
halim-46503294

Competitive Programming 4 The Lower Bound Of Programming Contests In


The 2020s 4th Edition Steven Halim

https://ebookbell.com/product/competitive-programming-4-the-lower-
bound-of-programming-contests-in-the-2020s-4th-edition-steven-
halim-46503296
Competitive Programming In Python 128 Algorithms To Develop Your
Coding Skills 1st Edition Christoph Drr

https://ebookbell.com/product/competitive-programming-in-
python-128-algorithms-to-develop-your-coding-skills-1st-edition-
christoph-drr-22000366

Competitive Programming 3 The New Lower Bound Of Programming Contests


3rd Steven Halim

https://ebookbell.com/product/competitive-programming-3-the-new-lower-
bound-of-programming-contests-3rd-steven-halim-10205022

Competitive Programming Guide Learning And Enhancing Algorithms With


Contests Bharat Mishra

https://ebookbell.com/product/competitive-programming-guide-learning-
and-enhancing-algorithms-with-contests-bharat-mishra-55749594

Competitive Programming 4 Book 1 4th Steven Halim Felix Halim

https://ebookbell.com/product/competitive-programming-4-book-1-4th-
steven-halim-felix-halim-46668790

Competitive Programming 4 Book 1 4th Edition Steven Halim Felix Halim

https://ebookbell.com/product/competitive-programming-4-book-1-4th-
edition-steven-halim-felix-halim-46829276
Contents

Foreword v

Preface vi

Authors’ Profiles and Copyright xi

Convention and Problem Categorization xii

List of Abbreviations xiii

List of Tables xiv

List of Figures xv

1 Introduction 1
1.1 Competitive Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Tips to be Competitive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2.1 Tip 2: Quickly Identify Problem Types . . . . . . . . . . . . . . . . . . . . . 4
1.2.2 Tip 3: Do Algorithm Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2.3 Tip 4: Master Programming Languages . . . . . . . . . . . . . . . . . . . . . 8
1.2.4 Tip 5: Master the Art of Testing Code . . . . . . . . . . . . . . . . . . . . . . 10
1.2.5 Tip 6: Practice and More Practice . . . . . . . . . . . . . . . . . . . . . . . . 12
1.2.6 Tip 7: Team Work (ICPC Only) . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.3 Getting Started: The Ad Hoc Problems . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.4 Chapter Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

2 Data Structures and Libraries 21


2.1 Overview and Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.2 Data Structures with Built-in Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.2.1 Linear Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.2.2 Non-Linear Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.3 Data Structures with Our-Own Libraries . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.3.1 Graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.3.2 Union-Find Disjoint Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.3.3 Segment Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.3.4 Fenwick Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.4 Chapter Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

3 Problem Solving Paradigms 39


3.1 Overview and Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.2 Complete Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.2.1 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.2.2 Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.3 Divide and Conquer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

i
CONTENTS 
c Steven & Felix

3.3.1 Interesting Usages of Binary Search . . . . . . . . . . . . . . . . . . . . . . . 47


3.4 Greedy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
3.4.1 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
3.5 Dynamic Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.5.1 DP Illustration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.5.2 Classical Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
3.5.3 Non Classical Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
3.6 Chapter Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

4 Graph 71
4.1 Overview and Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
4.2 Graph Traversal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
4.2.1 Depth First Search (DFS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
4.2.2 Breadth First Search (BFS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
4.2.3 Finding Connected Components (in an Undirected Graph) . . . . . . . . . . 73
4.2.4 Flood Fill - Labeling/Coloring the Connected Components . . . . . . . . . . 74
4.2.5 Topological Sort (of a Directed Acyclic Graph) . . . . . . . . . . . . . . . . . 75
4.2.6 Bipartite Graph Check . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
4.2.7 Graph Edges Property Check via DFS Spanning Tree . . . . . . . . . . . . . 76
4.2.8 Finding Articulation Points and Bridges (in an Undirected Graph) . . . . . . 77
4.2.9 Finding Strongly Connected Components (in a Directed Graph) . . . . . . . 80
4.3 Minimum Spanning Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
4.3.1 Overview and Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
4.3.2 Kruskal’s Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
4.3.3 Prim’s Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
4.3.4 Other Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
4.4 Single-Source Shortest Paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
4.4.1 Overview and Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
4.4.2 SSSP on Unweighted Graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
4.4.3 SSSP on Weighted Graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
4.4.4 SSSP on Graph with Negative Weight Cycle . . . . . . . . . . . . . . . . . . . 93
4.5 All-Pairs Shortest Paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
4.5.1 Overview and Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
4.5.2 Explanation of Floyd Warshall’s DP Solution . . . . . . . . . . . . . . . . . . 96
4.5.3 Other Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
4.6 Maximum Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
4.6.1 Overview and Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
4.6.2 Ford Fulkerson’s Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
4.6.3 Edmonds Karp’s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
4.6.4 Other Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
4.7 Special Graphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
4.7.1 Directed Acyclic Graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
4.7.2 Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
4.7.3 Eulerian Graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
4.7.4 Bipartite Graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
4.8 Chapter Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

5 Mathematics 121
5.1 Overview and Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
5.2 Ad Hoc Mathematics Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
5.3 Java BigInteger Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
5.3.1 Basic Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
5.3.2 Bonus Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126

ii
CONTENTS 
c Steven & Felix

5.4 Combinatorics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129


5.4.1 Fibonacci Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
5.4.2 Binomial Coefficients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
5.4.3 Catalan Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
5.4.4 Other Combinatorics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
5.5 Number Theory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
5.5.1 Prime Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
5.5.2 Greatest Common Divisor (GCD) & Least Common Multiple (LCM) . . . . 135
5.5.3 Factorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
5.5.4 Finding Prime Factors with Optimized Trial Divisions . . . . . . . . . . . . . 136
5.5.5 Working with Prime Factors . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
5.5.6 Functions Involving Prime Factors . . . . . . . . . . . . . . . . . . . . . . . . 138
5.5.7 Modulo Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
5.5.8 Extended Euclid: Solving Linear Diophantine Equation . . . . . . . . . . . . 141
5.5.9 Other Number Theoretic Problems . . . . . . . . . . . . . . . . . . . . . . . . 142
5.6 Probability Theory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
5.7 Cycle-Finding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
5.7.1 Solution using Efficient Data Structure . . . . . . . . . . . . . . . . . . . . . . 143
5.7.2 Floyd’s Cycle-Finding Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . 143
5.8 Game Theory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
5.8.1 Decision Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
5.8.2 Mathematical Insights to Speed-up the Solution . . . . . . . . . . . . . . . . 146
5.8.3 Nim Game . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
5.9 Powers of a (Square) Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
5.9.1 The Idea of Efficient Exponentiation . . . . . . . . . . . . . . . . . . . . . . . 147
5.9.2 Square Matrix Exponentiation . . . . . . . . . . . . . . . . . . . . . . . . . . 148
5.10 Chapter Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149

6 String Processing 151


6.1 Overview and Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
6.2 Basic String Processing Skills . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
6.3 Ad Hoc String Processing Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
6.4 String Matching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
6.4.1 Library Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
6.4.2 Knuth-Morris-Pratt (KMP) Algorithm . . . . . . . . . . . . . . . . . . . . . . 156
6.4.3 String Matching in a 2D Grid . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
6.5 String Processing with Dynamic Programming . . . . . . . . . . . . . . . . . . . . . 160
6.5.1 String Alignment (Edit Distance) . . . . . . . . . . . . . . . . . . . . . . . . . 160
6.5.2 Longest Common Subsequence . . . . . . . . . . . . . . . . . . . . . . . . . . 161
6.5.3 Palindrome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
6.6 Suffix Trie/Tree/Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
6.6.1 Suffix Trie and Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
6.6.2 Suffix Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
6.6.3 Applications of Suffix Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
6.6.4 Suffix Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
6.6.5 Applications of Suffix Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
6.7 Chapter Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174

7 (Computational) Geometry 175


7.1 Overview and Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
7.2 Basic Geometry Objects with Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . 176
7.2.1 0D Objects: Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
7.2.2 1D Objects: Lines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177

iii
CONTENTS 
c Steven & Felix

7.2.3 2D Objects: Circles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181


7.2.4 2D Objects: Triangles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
7.2.5 2D Objects: Quadrilaterals . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
7.2.6 3D Objects: Spheres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
7.2.7 3D Objects: Others . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
7.3 Polygons with Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
7.3.1 Polygon Representation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
7.3.2 Perimeter of a Polygon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
7.3.3 Area of a Polygon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
7.3.4 Checking if a Polygon is Convex . . . . . . . . . . . . . . . . . . . . . . . . . 189
7.3.5 Checking if a Point is Inside a Polygon . . . . . . . . . . . . . . . . . . . . . . 189
7.3.6 Cutting Polygon with a Straight Line . . . . . . . . . . . . . . . . . . . . . . 190
7.3.7 Finding the Convex Hull of a Set of Points . . . . . . . . . . . . . . . . . . . 191
7.4 Divide and Conquer Revisited . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
7.5 Chapter Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196

8 More Advanced Topics 197


8.1 Overview and Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
8.2 Problem Decomposition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
8.2.1 Two Components: Binary Search the Answer and Other . . . . . . . . . . . . 197
8.2.2 Two Components: SSSP and DP . . . . . . . . . . . . . . . . . . . . . . . . . 198
8.2.3 Two Components: Involving Graph . . . . . . . . . . . . . . . . . . . . . . . 199
8.2.4 Two Components: Involving Mathematics . . . . . . . . . . . . . . . . . . . . 199
8.2.5 Three Components: Prime Factors, DP, Binary Search . . . . . . . . . . . . . 199
8.2.6 Three Components: Complete Search, Binary Search, Greedy . . . . . . . . . 199
8.3 More Advanced Search Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
8.3.1 Informed Search: A* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
8.3.2 Depth Limited Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
8.3.3 Iterative Deepening Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
8.3.4 Iterative Deepening A* (IDA*) . . . . . . . . . . . . . . . . . . . . . . . . . . 204
8.4 More Advanced Dynamic Programming Techniques . . . . . . . . . . . . . . . . . . . 205
8.4.1 Emerging Technique: DP + bitmask . . . . . . . . . . . . . . . . . . . . . . . 205
8.4.2 Chinese Postman/Route Inspection Problem . . . . . . . . . . . . . . . . . . 205
8.4.3 Compilation of Common DP States . . . . . . . . . . . . . . . . . . . . . . . 206
8.4.4 MLE/TLE? Use Better State Representation! . . . . . . . . . . . . . . . . . . 207
8.4.5 MLE/TLE? Drop One Parameter, Recover It from Others! . . . . . . . . . . 208
8.4.6 Your Parameter Values Go Negative? Use Offset Technique . . . . . . . . . . 209
8.5 Chapter Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211

A Hints/Brief Solutions 213

B uHunt 225

C Credits 227

D Plan for the Third Edition 228

Bibliography 229

iv
CONTENTS 
c Steven & Felix

Foreword
Long time ago (exactly the Tuesday November 11th 2003 at 3:55:57 UTC), I received an e-mail
with the following sentence: I should say in a simple word that with the UVa Site, you have given
birth to a new CIVILIZATION and with the books you write (he meant “Programming Challenges:
The Programming Contest Training Manual” [34], coauthored with Steven Skiena), you inspire the
soldiers to carry on marching. May you live long to serve the humanity by producing super-human
programmers.
Although it’s clear that was an exaggeration, to tell the truth I started thinking a bit about and
I had a dream: to create a community around the project I had started as a part of my teaching
job at UVa, with persons from everywhere around the world to work together after that ideal. Just
by searching in Internet I immediately found a lot of people who was already creating a web-ring
of sites with excellent tools to cover the many lacks of the UVa site.
The more impressive to me was the ’Methods to Solve’ from Steven Halim, a very young
student from Indonesia and I started to believe that the dream would become real a day, because
the contents of the site were the result of a hard work of a genius of algorithms and informatics.
Moreover his declared objectives matched the main part of my dream: to serve the humanity. And
the best of the best, he has a brother with similar interest and capabilities, Felix Halim.
It’s a pity it takes so many time to start a real collaboration, but the life is as it is. Fortunately,
all of us have continued working in a parallel way and the book that you have in your hands is the
best proof.
I can’t imagine a better complement for the UVa Online Judge site, as it uses lots of examples
from there carefully selected and categorized both by problem type and solving techniques, an
incredible useful help for the users of the site. By mastering and practicing most programming
exercises in this book, reader can easily go to 500 problems solved in UVa online judge, which will
place them in top 400-500 within ≈100000 UVa OJ users.
Then it’s clear that the book “Competitive Programming: Increasing the Lower Bound of
Programming Contests” is suitable for programmers who wants to improve their ranks in upcoming
ICPC regionals and IOIs. The two authors have gone through these contests (ICPC and IOI)
themselves as contestants and now as coaches. But it’s also an essential colleague for the newcomers,
because as Steven and Felix say in the introduction ‘the book is not meant to be read once, but
several times’.
Moreover it contains practical C++ source codes to implement the given algorithms. Because
understand the problems is a thing, knowing the algorithms is another, and implementing them
well in short and efficient code is tricky. After you read this extraordinary book three times you
will realize that you are a much better programmer and, more important, a more happy person.

Miguel A. Revilla, University of Valladolid


UVa Online Judge site creator; ACM-ICPC International Steering Committee Member and Problem Archivist
http://uva.onlinejudge.org; http://livearchive.onlinejudge.org

v
CONTENTS 
c Steven & Felix

Preface
This book is a must have for every competitive programmer to master during their middle phase
of their programming career if they wish to take a leap forward from being just another ordinary
coder to being among one of the top finest programmer in the world.
Typical readers of this book would be:
1. University students who are competing in the annual ACM International Collegiate Program-
ming Contest (ICPC) [38] Regional Contests (including the World Finals),
2. Secondary or High School Students who are competing in the annual International Olympiad
in Informatics (IOI) [21] (including the National level),
3. Coaches who are looking for comprehensive training material for their students [13],
4. Anyone who loves solving problems through computer programs. There are numerous pro-
gramming contests for those who are no longer eligible for ICPC like TopCoder Open, Google
CodeJam, Internet Problem Solving Contest (IPSC), etc.

Prerequisites
This book is not written for novice programmers. When we wrote this book, we set it for readers
who have basic knowledge in basic programming methodology, familiar with at least one of these
programming languages (C/C++ or Java, preferably both), and have passed basic data structures
and algorithms course typically taught in year one of Computer Science university curriculum.

Specific to the ACM ICPC Contestants


We know that one cannot probably win the ACM ICPC regional just by mastering the current
version (2nd edition) of this book. While we have included a lot of materials in this book, we are
much aware that much more than what this book can offer, are required to achieve that feat. Some
reference pointers are listed in the chapter notes for those who are hungry for more. We believe,
however, that your team would fare much better in future ICPCs after mastering this book.

Specific to the IOI Contestants

Same preface as above but with this additional Table 1. This table shows a list of topics that
are currently not yet included in the IOI syllabus [10]. You can skip these items until you enter
university (and join that university’s ACM ICPC teams). However, learning them in advance may
be beneficial as some harder tasks in IOI may require some of these knowledge.

vi
CONTENTS 
c Steven & Felix

Topic In This Book


Data Structures: Union-Find Disjoint Sets Section 2.3.2
Graph: Finding SCCs, Max Flow, Bipartite Graph Section 4.2.1, 4.6.3, 4.7.4
Math: BigInteger, Probability, Nim Games, Matrix Power Section 5.3, 5.6, 5.8, 5.9
String Processing: Suffix Tree/Array Section 6.6
More Advanced Topics: A*/IDA* Section 8.3

Table 1: Not in IOI Syllabus [10] Yet

We know that one cannot win a medal in IOI just by mastering the current version of this book.
While we believe many parts of the IOI syllabus have been included in this book – which should
give you a respectable score in future IOIs – we are well aware that modern IOI tasks requires more
problem solving skills and creativity that we cannot teach via this book. So, keep practicing!

Specific to the Teachers/Coaches


This book is used in Steven’s CS3233 - ‘Competitive Programming’ course in the School of Com-
puting, National University of Singapore. It is conducted in 13 teaching weeks using the following
lesson plan (see Table 2). The PDF slides (only the public version) are given in the companion web
site of this book. Hints/brief solutions of the written exercises in this book are given in Appendix
A. Fellow teachers/coaches are free to modify the lesson plan to suit your students’ needs.

Wk Topic In This Book


01 Introduction Chapter 1
02 Data Structures & Libraries Chapter 2
03 Complete Search, Divide & Conquer, Greedy Section 3.2-3.4
04 Dynamic Programming 1 (Basic Ideas) Section 3.5
05 Graph 1 (DFS/BFS/MST) Chapter 4 up to Section 4.3
06 Graph 2 (Shortest Paths; DAG-Tree) Section 4.4-4.5; 4.7.1-4.7.2
- Mid semester break -
07 Mid semester team contest -
08 Dynamic Programming 2 (More Techniques) Section 6.5; 8.4
09 Graph 3 (Max Flow; Bipartite Graph) Section 4.6.3; 4.7.4
10 Mathematics (Overview) Chapter 5
11 String Processing (Basic skills, Suffix Array) Chapter 6
12 (Computational) Geometry (Libraries) Chapter 7
13 Final team contest All, including Chapter 8
- No final exam -

Table 2: Lesson Plan

To All Readers
Due to the diversity of its content, this book is not meant to be read once, but several times. There
are many written exercises and programming problems (≈ 1198) scattered throughout the body
text of this book which can be skipped at first if the solution is not known at that point of time,
but can be revisited later after the reader has accumulated new knowledge to solve it. Solving
these exercises will strengthen the concepts taught in this book as they usually contain interesting
twists or variants of the topic being discussed. Make sure to attempt them once.
We believe this book is and will be relevant to many university and high school students as
ICPC and IOI will be around for many years ahead. New students will require the ‘basic’ knowledge
presented in this book before hunting for more challenges after mastering this book. But before
you assume anything, please check this book’s table of contents to see what we mean by ‘basic’.

vii
CONTENTS 
c Steven & Felix

We will be happy if in the year 2010 (the publication year of the first edition of this book)
and beyond, the lower bound level of competitions in ICPC and IOI increases because many of the
contestants have mastered the content of this book. That is, we want to see fewer teams solving
very few problems (≤ 2) in future ICPCs and fewer contestants obtaining less than 200 marks in
future IOIs. We also hope to see many ICPC and IOI coaches around the world, especially in South
East Asia, adopt this book knowing that without mastering the topics in and beyond this book,
their students have very little chance of doing well in future ICPCs and IOIs. If such increase in
‘required lowerbound knowledge’ happens, this book would have fulfilled its objective of advancing
the level of human knowledge in this era.

Changes for the Second Edition


There are substantial changes between the first and the second edition of this book. As the authors,
we have learned a number of new things and solved hundreds of programming problems during the
one year gap between these two editions. We also have received several feedbacks from the readers,
especially from Steven’s CS3233 class Sem 2 AY2010/2011 students, that we have incorporated in
the second edition.
Here is a summary of the important changes for the second edition:

• The first noticeable change is the layout. We now have more information density per page.
The 2nd edition uses single line spacing instead of one half line spacing in the 1st edition.
The positioning of small figures is also enhanced so that we have a more compact layout.
This is to avoid increasing the number of pages by too much while we add more content.
• Some minor bug in our example codes (both the ones shown in the book and the soft copy
given in the companion web site) are fixed. All example codes now have much more meaningful
comments to help readers understand the code.
• Several known language issues (typo, grammatical, stylistic) have been corrected.
• On top of enhancing the writing of existing data structures, algorithms, and programming
problems, we also add these new materials in each chapter:

1. Much more Ad Hoc problems to kick start this book (Section 1.3).
2. Lightweight set of Boolean (bit manipulation techniques) (Section 2.2.1), Implicit Graph
(Section 2.3.1), and Fenwick Tree data structure (Section 2.3.4).
3. More DP: Clearer explanation of the bottom-up DP, O(n log k) solution for LIS problem,
Introducing: 0-1 Knapsack/Subset Sum, DP TSP (bitmask technique) (Section 3.5.2).
4. Reorganization of graph material into: Graph Traversal (both DFS and BFS), Mini-
mum Spanning Tree, Shortest Paths (Single-Source and All-Pairs), Maximum Flow, and
Special Graphs. New topics: Prim’s MST algorithm, Explaining DP as a traversal on
implicit DAG (Section 4.7.1), Eulerian Graph (Section 4.7.3), Alternating Path Bipartite
Matching algorithm (Section 4.7.4).
5. Reorganization of mathematics topics (Chapter 5) into: Ad Hoc, Java BigInteger, Com-
binatorics, Number Theory, Probability Theory, Cycle-Finding, Game Theory (new),
and Powers of a (Square) Matrix (new). Each topic is rewritten and made clearer.
6. Basic string processing skills (Section 6.2), more string problems (Section 6.3), string
matching (Section 6.4), and an enhanced Suffix Tree/Array explanation (Section 6.6).
7. Much more geometric libraries (Chapter 7), especially on points, lines, and polygons.
8. New Chapter 8: Discussion on problem decomposition; More advanced search techniques
(A*, Depth Limited Search, Iterative Deepening, IDA*); More advanced DP: more bit-
masks techniques, Chinese Postman Problem, compilation of common DP states, dis-
cussion on better DP states, and some other harder DP problems.

viii
CONTENTS 
c Steven & Felix

• Many existing figures in this book are re-drawn and enhanced. Many new figures are added
to help explain the concepts more clearly.

• The first edition is mainly written using ICPC and C++ viewpoint. The second edition is
now written in a more balanced viewpoint between ICPC versus IOI and C++ versus Java.
Java support is strongly enhanced in the second edition. However, we do not support any
other programming languages as of now.

• Steven’s ‘Methods to Solve’ website is now fully integrated in this book in form of ‘one liner
hints’ per problem and the useful problem index at the back of this book. Now, reaching
1000 problems solved in UVa online judge is no longer a wild dream (we now consider that
this feat is doable by a serious 4-year Computer Science university undergraduate).

• Some examples in the first edition use old programming problems. In the second edition,
some examples are replaced/added with the newer examples.

• Addition of around 600 more programming exercises that Steven & Felix have solved in UVa
online judge and Live Archive between the first and second edition. We also give much more
conceptual exercises throughout the book with hints/short solutions as appendix.

• Addition of short profiles of data structure/algorithm inventors adapted from Wikipedia [42]
or other sources. It is nice to know a little bit more about the man behind these algorithms.

Web Sites
This book has an official companion web site at: http://sites.google.com/site/stevenhalim.
In that website, you can download the soft copy of sample source codes and PDF slides
(but only the public/simpler version) used in Steven’s CS3233 classes.
All programming exercises in this book are integrated in:
http://felix-halim.net/uva/hunting.php, and in
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=118

Acknowledgments for the First Edition


Steven wants to thank:

• God, Jesus Christ, Holy Spirit, for giving talent and passion in this competitive programming.

• My lovely wife, Grace Suryani, for allowing me to spend our precious time for this project.

• My younger brother and co-author, Felix Halim, for sharing many data structures, algorithms,
and programming tricks to improve the writing of this book.

• My father Lin Tjie Fong and mother Tan Hoey Lan for raising us and encouraging us to do
well in our study and work.

• School of Computing, National University of Singapore, for employing me and allowing me


to teach CS3233 - ‘Competitive Programming’ module from which this book is born.

• NUS/ex-NUS professors/lecturers who have shaped my competitive programming and coach-


ing skills: Prof Andrew Lim Leong Chye, Dr Tan Sun Teck, Aaron Tan Tuck Choy, Dr Sung
Wing Kin, Ken, Dr Alan Cheng Holun.

• My friend Ilham Winata Kurnia for proof reading the manuscript of the first edition.

• Fellow Teaching Assistants of CS3233 and ACM ICPC Trainers @ NUS: Su Zhan, Ngo Minh
Duc, Melvin Zhang Zhiyong, Bramandia Ramadhana.

ix
CONTENTS 
c Steven & Felix

• My CS3233 students in Sem2 AY2008/2009 who inspired me to come up with the lecture
notes and students in Sem2 AY2009/2010 who verified the content of the first edition of this
book and gave the initial Live Archive contribution

Acknowledgments for the Second Edition


Additionally, Steven wants to thank:

• ≈ 550 buyers of the 1st edition as of 1 August 2011. Your supportive responses encourage us!

• Fellow Teaching Assistant of CS3233 @ NUS: Victor Loh Bo Huai.

• My CS3233 students in Sem2 AY2010/2011 who contributed in both technical and presenta-
tion aspects of the second edition of this book, in alphabetical order: Aldrian Obaja Muis,
Bach Ngoc Thanh Cong, Chen Juncheng, Devendra Goyal, Fikril Bahri, Hassan Ali Askari,
Harta Wijaya, Hong Dai Thanh, Koh Zi Chun, Lee Ying Cong, Peter Phandi, Raymond
Hendy Susanto, Sim Wenlong Russell, Tan Hiang Tat, Tran Cong Hoang, Yuan Yuan, and
one other student who prefers to be anonymous (class photo is shown below).

• The proof readers: Seven of CS3233 students above (underlined) plus Tay Wenbin.

• Last but not least, Steven wants to re-thank his wife, Grace Suryani, for letting me do another
round of tedious book editing process while you are pregnant with our first baby.

To a better future of humankind,


Steven and Felix Halim
Singapore, 1 August 2011

x
CONTENTS 
c Steven & Felix

Authors’ Profiles
Steven Halim, PhD1
stevenhalim@gmail.com

Steven Halim is currently a lecturer in School


of Computing, National University of Singapore
(SoC, NUS). He teaches several programming
courses in NUS, ranging from basic program-
ming methodology, intermediate data struc-
tures and algorithms, and up to the ‘Competi-
tive Programming’ module that uses this book.
He is the coach of both NUS ACM ICPC teams
and Singapore IOI team. He participated in
several ACM ICPC Regional as student (Singa-
pore 2001, Aizu 2003, Shanghai 2004). So far,
he and other trainers @ NUS have successfully
groomed one ACM ICPC World Finalist team
(2009-2010) as well as two gold, four silver, and
six bronze IOI medallists (2009-2011).
As seen from the family photo, Steven is a happily married man. His wife, Grace Suryani, is
currently pregnant with our first baby during the time the second edition of this book is released.

Felix Halim, PhD Candidate2


felix.halim@gmail.com

Felix Halim is currently a PhD student in the same University: SoC,


NUS. In terms of programming contests, Felix has a much more colorful
reputation than his older brother. He was IOI 2002 contestant (rep-
resenting Indonesia). His ICPC teams (at that time, Bina Nusantara
University) took part in ACM ICPC Manila Regional 2003-2004-2005
and obtained rank 10th, 6th, and 10th respectively. Then, in his fi-
nal year, his team finally won ACM ICPC Kaohsiung Regional 2006 and
thus became ACM ICPC World Finalist @ Tokyo 2007 (Honorable Men-
tion). Today, he actively joins TopCoder Single Round Matches and his
highest rating is a yellow coder.

Copyright
No part of this book may be reproduced or transmitted in any form or by any means, electroni-
cally or mechanically, including photocopying, scanning, uploading to any information storage and
retrieval system.

1
PhD Thesis: “An Integrated White+Black Box Approach for Designing and Tuning Stochastic Local Search
Algorithms”, 2009.
2
Research area: “Large Scale Data Processing”.

xi
CONTENTS 
c Steven & Felix

Convention
There are a lot of C++ codes shown in this book. If they appear, they will be written using this
font. Many of them use typedefs, shortcuts, or macros that are commonly used by competitive
programmers to speed up the coding time. In this short section, we list down several examples.
Java support has been increased substantially in the second edition of this book. This book uses
Java which, as of now, does not support macros and typedefs.
// Suppress some compilation warning messages (only for VC++ users)
#define _CRT_SECURE_NO_DEPRECATE

// Shortcuts for "common" data types in contests


typedef long long ll; // comments that are mixed with code
typedef pair<int, int> ii; // are aligned to the right like this
typedef vector<ii> vii;
typedef vector<int> vi;
#define INF 1000000000 // 1 billion, safer than 2B for Floyd Warshall’s

// Common memset settings


//memset(memo, -1, sizeof memo); // initialize DP memoization table with -1
//memset(arr, 0, sizeof arr); // to clear array of integers

// Note that we abandon the usage of "REP" and "TRvii" in the second edition
// to reduce the confusion encountered by new programmers
The following shortcuts are frequently used in our C/C++/Java codes in this book:
// ans = a ? b : c; // to simplify: if (a) ans = b; else ans = c;
// index = (index + 1) % n; // from: index++; if (index >= n) index = 0;
// index = (index + n - 1) % n; // from: index--; if (index < 0) index = n - 1;
// int ans = (int)((double)d + 0.5); // for rounding to nearest integer
// ans = min(ans, new_computation) // we frequently use this min/max shortcut
// some codes uses short circuit && (AND) and || (OR)

Problem Categorization
As of 1 August 2011, Steven and Felix – combined – have solved 1502 UVa problems (≈ 51% of
the entire UVa problems). About ≈ 1198 of them are discussed and categorized in this book.
These problems are categorized according to a ‘load balancing’ scheme: If a problem can be
classified into two or more categories, it will be placed in the category with a lower number of
problems. This way, you may find problems ‘wrongly’ categorized or problems whose category does
not match the technique you use to solve it. What we can guarantee is this: If you see problem X
in category Y, then you know that we have solved problem X with the technique mentioned in the
section that discusses category Y.
If you need hints for any of the problems, you may turn to the index at the back of this book and
save yourself the time needed to flip through the whole book to understand any of the problems.
The index contains a sorted list of UVa/LA problems number (do a binary search!) which will help
locate the pages that contains the discussion of those problems (and the required data structures
and/or algorithms to solve that problem).
Utilize this categorization feature for your training! To diversify your problem solving skill, it is
a good idea to solve at least few problems from each category, especially the ones that we highlight
as must try * (we limit ourself to choose maximum 3 highlights per category).

xii
CONTENTS 
c Steven & Felix

Abbreviations MVC : Minimum Vertex Cover

OJ : Online Judge

PE : Presentation Error
A* : A Star
ACM : Association of Computing Machinery RB : Red-Black (BST)
AC : Accepted RMQ : Range Minimum (or Maximum) Query
APSP : All-Pairs Shortest Paths
AVL : Adelson-Velskii Landis (BST) RSQ : Range Sum Query
RTE : Run Time Error
BNF : Backus Naur Form
BFS : Breadth First Search SSSP : Single-Source Shortest Paths
BI : Big Integer SA : Suffix Array
BIT : Binary Indexed Tree SPOJ : Sphere Online Judge
BST : Binary Search Tree ST : Suffix Tree
STL : Standard Template Library
CC : Coin Change
CCW : Counter ClockWise TLE : Time Limit Exceeded
CF : Cumulative Frequency
USACO : USA Computing Olympiad
CH : Convex Hull
UVa : University of Valladolid [28]
CS : Computer Science
WA : Wrong Answer
DAG : Directed Acyclic Graph
WF : World Finals
DAT : Direct Addressing Table
D&C : Divide and Conquer
DFS : Depth First Search
DLS : Depth Limited Search
DP : Dynamic Programming

ED : Edit Distance

FT : Fenwick Tree

GCD : Greatest Common Divisor

ICPC : Intl Collegiate Programming Contest


IDS : Iterative Deepening Search
IDA* : Iterative Deepening A Star
IOI : International Olympiad in Informatics
IPSC : Internet Problem Solving Contest

LA : Live Archive [20]


LCA : Lowest Common Ancestor
LCM : Least Common Multiple
LCP : Longest Common Prefix
LCS1 : Longest Common Subsequence
LCS2 : Longest Common Substring
LIS : Longest Increasing Subsequence
LRS : Longest Repeated Substring

MCBM : Max Cardinality Bip Matching


MCM : Matrix Chain Multiplication
MCMF : Min-Cost Max-Flow
MIS : Maximum Independent Set
MLE : Memory Limit Exceeded
MPC : Minimum Path Cover
MSSP : Multi-Sources Shortest Paths
MST : Minimum Spanning Tree
MWIS : Max Weighted Independent Set

xiii
List of Tables

1 Not in IOI Syllabus [10] Yet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii


2 Lesson Plan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii

1.1 Recent ACM ICPC Asia Regional Problem Types . . . . . . . . . . . . . . . . . . . 4


1.2 Exercise: Classify These UVa Problems . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.3 Problem Types (Compact Form) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.4 Rule of Thumb for the ‘Worst AC Algorithm’ for various input size n . . . . . . . . 6

2.1 Example of a Cumulative Frequency Table . . . . . . . . . . . . . . . . . . . . . . . . 35

3.1 Running Bisection Method on the Example Function . . . . . . . . . . . . . . . . . . 48


3.2 DP Decision Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
3.3 UVa 108 - Maximum Sum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62

4.1 Graph Traversal Algorithm Decision Table . . . . . . . . . . . . . . . . . . . . . . . . 82


4.2 Floyd Warshall’s DP Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
4.3 SSSP/APSP Algorithm Decision Table . . . . . . . . . . . . . . . . . . . . . . . . . . 100

5.1 Part 1: Finding kλ, f (x) = (7x + 5)%12, x0 = 4 . . . . . . . . . . . . . . . . . . . . . 143


5.2 Part 2: Finding μ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
5.3 Part 3: Finding λ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144

6.1 Left/Right: Before/After Sorting; k = 1; Initial Sorted Order Appears . . . . . . . . 167


6.2 Left/Right: Before/After Sorting; k = 2; ‘GATAGACA’ and ‘GACA’ are Swapped . . . 168
6.3 Before and After sorting; k = 4; No Change . . . . . . . . . . . . . . . . . . . . . . . 168
6.4 String Matching using Suffix Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
6.5 Computing the Longest Common Prefix (LCP) given the SA of T = ‘GATAGACA’ . . 172

A.1 Exercise: Classify These UVa Problems . . . . . . . . . . . . . . . . . . . . . . . . . 213

xiv
List of Figures

1.1 Illustration of UVa 10911 - Forming Quiz Teams . . . . . . . . . . . . . . . . . . . . 2


1.2 UVa Online Judge and ACM ICPC Live Archive . . . . . . . . . . . . . . . . . . . . 12
1.3 USACO Training Gateway and Sphere Online Judge . . . . . . . . . . . . . . . . . . 12
1.4 Some references that inspired the authors to write this book . . . . . . . . . . . . . . 18

2.1 Examples of BST (Left) and (Max) Heap (Right) . . . . . . . . . . . . . . . . . . . . 26


2.2 Example of various Graph representations . . . . . . . . . . . . . . . . . . . . . . . . 29
2.3 Union-Find Disjoint Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.4 Segment Tree of Array A = {8, 7, 3, 9, 5, 1, 10} . . . . . . . . . . . . . . . . . . . . 33
2.5 Updating Array A to {8, 7, 3, 9, 5, 100, 10} . . . . . . . . . . . . . . . . . . . . . . . 33
2.6 Example of a Fenwick Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

3.1 8-Queens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.2 UVa 10360 [28] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.3 Visualization of LA 4793 - Robots on Ice . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.4 My Ancestor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.5 Visualization of UVa 410 - Station Balance . . . . . . . . . . . . . . . . . . . . . . . 52
3.6 UVa 410 - Observation 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
3.7 UVa 410 - Greedy Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
3.8 UVa 10382 - Watering Grass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.9 Bottom-Up DP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
3.10 Longest Increasing Subsequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
3.11 Coin Change . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
3.12 TSP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

4.1 Sample Graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72


4.2 Animation of BFS (from UVa 336 [28]) . . . . . . . . . . . . . . . . . . . . . . . . . . 73
4.3 Example of Toposort on DAG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
4.4 Animation of DFS when Run on the Sample Graph in Figure 4.1 . . . . . . . . . . . 77
4.5 Introducing two More DFS Attributes: dfs num and dfs low . . . . . . . . . . . . . 78
4.6 Finding Articulation Points with dfs num and dfs low . . . . . . . . . . . . . . . . . 79
4.7 Finding Bridges, also with dfs num and dfs low . . . . . . . . . . . . . . . . . . . . 79
4.8 An Example of a Directed Graph and its Strongly Connected Components (SCC) . . 80
4.9 Example of an MST Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
4.10 Animation of Kruskal’s Algorithm for an MST Problem . . . . . . . . . . . . . . . . 85
4.11 Animation of Prim’s Algorithm for the Same MST Problem as in Figure 4.9, left . . 86
4.12 From left to right: MST, ‘Maximum’ ST, Partial ‘Minimum’ ST, MS ‘Forest’ . . . . 86
4.13 Second Best ST (from UVa 10600 [28]) . . . . . . . . . . . . . . . . . . . . . . . . . . 87
4.14 Finding the Second Best Spanning Tree from the MST . . . . . . . . . . . . . . . . . 87
4.15 Minimax (UVa 10048 [28]) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
4.16 Dijkstra Animation on a Weighted Graph (from UVa 341 [28]) . . . . . . . . . . . . 92
4.17 -ve Weight . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
4.18 Bellman Ford’s can detect the presence of negative cycle (from UVa 558 [28]) . . . . 93

xv
LIST OF FIGURES 
c Steven & Felix

4.19 Floyd Warshall’s Explanation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97


4.20 Illustration of Max Flow (From UVa 820 [28] - ICPC World Finals 2000 Problem E) 101
4.21 Ford Fulkerson’s Method Implemented with DFS is Slow . . . . . . . . . . . . . . . . 102
4.22 What are the Max Flow value of these three residual graphs? . . . . . . . . . . . . . 102
4.23 Residual Graph of UVa 259 [28] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
4.24 Vertex Splitting Technique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
4.25 Comparison Between the Max Independent Paths versus Max Edge-Disjoint Paths . 105
4.26 An Example of Min Cost Max Flow (MCMF) Problem (from UVa 10594 [28]) . . . . 106
4.27 Special Graphs (L-to-R): DAG, Tree, Eulerian, Bipartite Graph . . . . . . . . . . . . 107
4.28 The Longest Path on this DAG is the Shortest Way to Complete the Project . . . . 108
4.29 Example of Counting Paths in DAG . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
4.30 The Given General Graph (left) is Converted to DAG . . . . . . . . . . . . . . . . . 109
4.31 The Given General Graph/Tree (left) is Converted to DAG . . . . . . . . . . . . . . 110
4.32 A: SSSP/APSP; B1-B2: Diameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
4.33 Eulerian . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
4.34 Bipartite Matching problem can be reduced to a Max Flow problem . . . . . . . . . 115
4.35 MCBM Variants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
4.36 Minimum Path Cover on DAG (from LA 3126 [20]) . . . . . . . . . . . . . . . . . . . 116
4.37 Alternating Path Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

6.1 String Alignment Example for A = ‘ACAATCC’ and B = ‘AGCATGC’ (score = 7) . . . 161
6.2 Suffix Trie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
6.3 Suffixes, Suffix Trie, and Suffix Tree of T = ‘GATAGACA’ . . . . . . . . . . . . . . . . 163
6.4 String Matching of T = ‘GATAGACA’ with Various Pattern Strings . . . . . . . . . . 164
6.5 Longest Repeated Substring of T = ‘GATAGACA’ . . . . . . . . . . . . . . . . . . . . 165
6.6 Generalized Suffix Tree of T1 = ‘GATAGACA’ and T2 = ‘CATA’ and their LCS . . . . 166
6.7 Suffix Tree and Suffix Array of T = ‘GATAGACA’ . . . . . . . . . . . . . . . . . . . . 166
6.8 The Suffix Array, LCP, and owner of T = ‘GATAGACA.CATA’ . . . . . . . . . . . . . 173

7.1 Distance to Line (left) and to Line Segment (right) . . . . . . . . . . . . . . . . . . . 179


7.2 Circles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
7.3 Circle Through 2 Points and Radius . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
7.4 Triangles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
7.5 Incircle and Circumcircle of a Triangle . . . . . . . . . . . . . . . . . . . . . . . . . . 184
7.6 Quadrilaterals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
7.7 Left: Sphere, Middle: Hemisphere and Great-Circle, Right gcDistance (Arc A-B) . . 186
7.8 Left: Convex Polygon, Right: Concave Polygon . . . . . . . . . . . . . . . . . . . . . 189
7.9 Left: inside, Middle: also inside, Right: outside . . . . . . . . . . . . . . . . . . . . . 190
7.10 Left: Before Cut, Right: After Cut . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
7.11 Rubber Band Analogy for Finding Convex Hull . . . . . . . . . . . . . . . . . . . . . 191
7.12 Sorting Set of Points by Their Angles w.r.t a Pivot (Point 0) . . . . . . . . . . . . . 192
7.13 The Main Part of Graham’s Scan algorithm . . . . . . . . . . . . . . . . . . . . . . . 192
7.14 Athletics Track (from UVa 11646) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195

8.1 Illustration for ACM ICPC WF2009 - A - A Careful Approach . . . . . . . . . . . . 200


8.2 15 Puzzle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
8.3 An Example of Chinese Postman Problem . . . . . . . . . . . . . . . . . . . . . . . . 206
8.4 The Descent Path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
8.5 Illustration for ACM ICPC WF2010 - J - Sharing Chocolate . . . . . . . . . . . . . . 208

B.1 Steven’s statistics as of 1 August 2011 . . . . . . . . . . . . . . . . . . . . . . . . . . 225


B.2 Hunting the next easiest problems using ‘dacu’ . . . . . . . . . . . . . . . . . . . . . 226
B.3 The programming exercises in this book are integrated in uHunt . . . . . . . . . . . 226
B.4 Steven’s & Felix’s progress in UVa online judge (2000-present) . . . . . . . . . . . . 226

xvi
Chapter 1

Introduction

I want to compete in ACM ICPC World Finals!


— A dedicated student

1.1 Competitive Programming


‘Competitive Programming’ in summary, is this: “Given well-known Computer Science (CS) prob-
lems, solve them as quickly as possible!”.
Let’s digest the terms one by one. The term ‘well-known CS problems’ implies that in com-
petitive programming, we are dealing with solved CS problems and not research problems (where
the solutions are still unknown). Definitely, some people (at least the problem author) have solved
these problems before. ‘Solve them’ implies that we1 must push our CS knowledge to a certain
required level so that we can produce working codes that can solve these problems too – in terms
of getting the same output as the problem setter using the problem setter’s secret2 test data. ‘As
quickly as possible’ is the competitive element which is a very natural human behavior.
Please note that being well-versed in competitive programming is not the end goal. It is just
the means. The true end goal is to produce all-rounder computer scientists/programmers who are
much more ready to produce better software or to face harder CS research problems in the future.
The founders of ACM International Collegiate Programming Contest (ICPC) [38] have this vision
and we, the authors, agree with it. With this book, we play our little roles in preparing current
and future generations to be more competitive in dealing with well-known CS problems frequently
posed in the recent ICPCs and International Olympiad in Informatics (IOI)s.

Illustration on solving UVa Online Judge [28] Problem Number 10911 (Forming Quiz Teams).

Abridged Problem Description:


Let (x, y) be the coordinate of a student’s house on a 2D plane. There are 2N students and we
want to pair them into N groups. Let di be Nthe distance between the houses of 2 students in
group i. Form N groups such that cost = i=1 di is minimized. Output the minimum cost.
Constraints: N ≤ 8; 0 ≤ x, y ≤ 1000.
Sample input:
N = 2; Coordinates of the 2N = 4 houses are {1, 1}, {8, 6}, {6, 8}, and {1, 3}.
Sample output:
cost = 4.83.
Think first, try not to flip this page immediately!

1
Some programming competitions are done in team setting to encourage teamwork as software engineers usually
do not work alone in real life.
2
By hiding the actual test data from the problem statement, competitive programming encourages the problem
solvers to exercise their mental strength to think of possible corner cases of the problem and test their program with
those cases. This is typical in real life when software engineers have to test their software a lot to make sure the
software met the requirements set by the customers.

1
1.2. TIPS TO BE COMPETITIVE 
c Steven & Felix

Figure 1.1: Illustration of UVa 10911 - Forming Quiz Teams

Now, ask yourself, which one of the following best describes you? Note that if you are unclear
with the material or terminologies shown in this chapter, you can re-read it after going through
this book once.

• Non-competitive programmer A (a.k.a the blurry one):


Step 1: He reads the problem and confused; He has never seen this kind of problem before.
Step 2: He tries to code something, starting from reading the non-trivial input and output.
Step 3: He then realizes that all his attempts fail:
Greedy solution: Pair students based on shortest distances gives Wrong Answer (WA).
Complete search using backtracking gives Time Limit Exceeded (TLE).
After 5 hours of labor (typical contest time), no Accepted (AC) solution is produced.
• Non-competitive programmer B (Give up):
Step 1: Read the problem...
Then realize that he has seen this kind of problem before.
But also remember that he has not learned how to solve this kind of problem...
He is not aware of a simple solution for this problem: Dynamic Programming (DP)...
Step 2: Skip the problem and read another problem in the problem set.
• (Still) non-competitive programmer C (Slow):
Step 1: Read the problem and realize that it is a ‘matching on general graph’ problem.
In general, this problem must be solved using ‘Edmonds’ Blossom’ algorithm [6].
But since the input size is small, this problem is solvable using DP!
The DP state is a bitmask that describes a matching status,
and matching unmatched students i and j will turn on two bits i and j in the bitmask.
Step 2: Code I/O routine, write recursive top-down DP, test the solution, debug >.<...
Step 3: Only after 3 hours, his solution is judged as AC (passed all secret test data).
• Competitive programmer D:
Same as programmer C, but completing all the steps above in less than 30 minutes.
• Very Competitive programmer E:
A very competitive programmer (e.g. the red ‘target’ coders in TopCoder [19]) should
solve this ‘well known’ problem in less than 15 minutes...

1.2 Tips to be Competitive


If you strive to be like competitive programmers D or E above – that is, if you want to do well to
qualify and get a medal in IOI [21], or to qualify for ACM ICPC [38] nationals, regionals, and up
to the world finals, or in other programming contests – then this book is definitely for you!
In the subsequent chapters, you will learn basic to more intermediate/advanced data structures
and algorithms frequently appearing in recent programming contests, compiled from many sources
[30, 5, 31, 3, 24, 32, 26, 34, 1, 23, 4, 33, 25, 36, 27] (see Figure 1.4).

2
1.2. TIPS TO BE COMPETITIVE 
c Steven & Felix

However, you will not just learn the data structures and algorithms, but also how to implement
them efficiently and apply them to appropriate contest problems. On top of that, you will also
learn many programming tips mainly taken from our own experience that can be helpful in contest
situations. We start this book by giving you several general tips below:

Tip 1: Type Code Faster!


No kidding! Although this tip may not mean much as ICPC and (especially) IOI are not typing
contests, we have seen recent ICPCs where rank i and rank i + 1 are just separated by few minutes.
When you can solve the same number of problems as your competitor, it is now down to coding
skill (ability to produce shorter + correct code) and ... typing speed.
Try this typing test at http://www.typingtest.com and follow the instructions there on how
to improve your typing skill. Steven’s is ∼85-95 wpm and Felix’s is ∼55-65 wpm. You also need to
familiarize your fingers with the positions of the frequently used programming language characters,
e.g. braces {} or () or <>, semicolon ‘;’, single quote for ‘char’, double quotes for “string”, etc.
As a little practice, try typing this C++ code as fast as possible.

/* Forming Quiz Teams, the solution for UVa 10911 above */

#include <algorithm> // note: if you have problems understanding this C++ code
#include <cmath> // (not the algorithm)
#include <cstdio> // please consult your basic programming text books first...
#include <cstring> // the explanation of this Dynamic Programming solution
using namespace std; // can be found in Chapter 3 and Chapter 8 later.
// See Section 2.2.1 for this bitmask technique
// using global variables is not a good software engineering practice,
int N; // but it is OK for competitive programming
double dist[20][20], memo[1 << 16]; // 1 << 16 is 2^16, recall that max N = 8

double matching(int bitmask) { // DP state = bitmask


// see that we initialize the array with -1 in the main function
if (memo[bitmask] > -0.5) // this state has been computed before
return memo[bitmask]; // simply lookup the memo table
if (bitmask == (1 << (2 * N)) - 1) // all are already matched
return memo[bitmask] = 0; // cost is 0

double ans = 2000000000.0; // initialize with a large value


for (int p1 = 0; p1 < 2 * N; p1++)
if (!(bitmask & (1 << p1))) { // if this bit is off
for (int p2 = p1 + 1; p2 < 2 * N; p2++)
if (!(bitmask & (1 << p2))) // if this different bit is also off
ans = min(ans,
dist[p1][p2] + matching(bitmask | (1 << p1) | (1 << p2)));
break; // important step, will be discussed in Chapter 3 & 8 later
}

return memo[bitmask] = ans; // store result in a memo table and return


}

int main() {
char line[1000], name[1000];
int i, j, caseNo = 1, x[20], y[20];
// to simplify testing, redirect input file to stdin
// freopen("10911.txt", "r", stdin);

3
1.2. TIPS TO BE COMPETITIVE 
c Steven & Felix

// we use gets(line) to read input line by line


while (sscanf(gets(line), "%d", &N), N) { // yes, we can do this :)
for (i = 0; i < 2 * N; i++)
sscanf(gets(line), "%s %d %d", &name, &x[i], &y[i]);

for (i = 0; i < 2 * N; i++) // build pairwise distance table


for (j = 0; j < 2 * N; j++) // have you used ‘hypot’ before?
dist[i][j] = hypot((double)x[i] - x[j], (double)y[i] - y[j]);

// use DP to solve minimum weighted perfect matching on small general graph


// this is a trick to initialize the memo table with -1
memset(memo, -1, sizeof memo);
printf("Case %d: %.2lf\n", caseNo++, matching(0));
} } // return 0;

FYI, the explanation of this Dynamic Programming algorithm with bitmask technique is given in
Section 2.2.1, 3.5, and 8.4.1. You do not have to be alarmed if you do not understand it yet.

1.2.1 Tip 2: Quickly Identify Problem Types


In ICPCs, the contestants (teams) are given a set of problems (≈ 7-11 problems) of varying types.
From our observation of recent ICPC Asia Regional problem sets, we can categorize the problems
types and their rate of appearance as in Table 1.1.
In IOIs (2009-2010), the contestants are given 8 tasks over 2 days (6 tasks in 2011) that covers
items no 1-5 and 10, plus a much smaller subset of items no 6-10 in Table 1.1. For details, please
refer to the IOI syllabus 2009 [10] and the IOI 1989-2008 problem classification [39].

No Category In This Book Appearance Frequency


1. Ad Hoc Section 1.3 1-2
2. Complete Search (Iterative/Recursive) Section 3.2 1-2
3. Divide & Conquer Section 3.3 0-1
4. Greedy (only the original ones) Section 3.4 0-1
5. Dynamic Programming (only the original ones) Section 3.5 1-2 (can go up to 3)
6. Graph Chapter 4 1-2
7. Mathematics Chapter 5 1-2
8. String Processing Chapter 6 1
9. Computational Geometry Chapter 7 1
10. Some Harder Problems Chapter 8 0-1
Total in Set 7-15 (usually ≤ 11)

Table 1.1: Recent ACM ICPC Asia Regional Problem Types

The classification in Table 1.1 is adapted from [29] and by no means complete. Some problems,
e.g. ‘sorting’, are not classified here as they are ‘trivial’ and only used as a ‘sub-routine’ in a bigger
problem. We do not include ‘recursion’ as it is embedded in other categories. We also omit ‘data
structure’ as usage of efficient data structure is integral for solving harder problems.
Of course there can be a mix and match of problem types: One problem can be classified
into more than one type, e.g. Floyd Warshall’s algorithm is either a solution for graph problem:
All-Pairs Shortest Paths (APSP, Section 4.5) or a Dynamic Programming (DP) algorithm (Section
3.5). Prim’s and Kruskal’s algorithms are either the solutions for another graph problem: Minimum
Spanning Tree (MST, Section 4.3) or Greedy algorithms (Section 3.4).
In the future, these classifications may change. One significant example is DP. This technique
was not known before 1940s, not frequently used in ICPCs or IOIs before mid 1990s, but it is a
must today. There are ≥ 3 DP problems (out of 11) in the recent ICPC World Finals 2010.

4
1.2. TIPS TO BE COMPETITIVE 
c Steven & Felix

Exercise 1.2.1: Read the UVa [28] problems shown in Table 1.2 and determine their problem
types. The first and the fifth ones have been filled-in for you. Filling this table is easy after
mastering this book as all techniques to solve these problems are discussed in this book. Please
revisit this exercise when you have finished reading this book once.

UVa Title Problem Type Hint


10360 Rat Attack Complete Search or Dynamic Programming Section 3.2 or 3.5
10341 Solve It Section 3.3
11292 Dragon of Loowater Section 3.4
11450 Wedding Shopping Section 3.5
10911 Forming Quiz Teams DP + bitmask Section 8.4.1
11635 Hotel Booking Section 8.2
11506 Angry Programmer Section 4.6
10243 Fire! Fire!! Fire!!! Section 4.7.1
10717 Mint Section 8.2
11512 GATTACA Section 6.6
10065 Useless Tile Packers Section 7.3.7

Table 1.2: Exercise: Classify These UVa Problems

The goal is not just to map problems into categories as in Table 1.1. After you are familiar with
most of the topics in this book, you can classify the problems into just four types as in Table 1.3.

No Category Confidence and Expected Solving Speed


A. I have solved this type before I am confident that I can solve it again now (and fast)
B. I have solved this type before But I know coding the solution takes time
C. I have seen this type before But that time I have not or cannot solve it
D. I have not seen this type before I may (not) be able to solve it now (under contest time)

Table 1.3: Problem Types (Compact Form)

To be competitive, you must frequently classify the problems that you read in the problem set into
type A (or at least type B).

1.2.2 Tip 3: Do Algorithm Analysis


Once you have designed an algorithm to solve a particular problem in a programming contest,
you must then ask this question: Given the maximum input bound (usually given in a good
problem description), can the currently developed algorithm, with its time/space complexity, pass
the time/memory limit given for that particular problem?
Sometimes, there are more than one way to attack a problem. However, some of them may be
incorrect, some of them are not fast enough, and some of them are ‘overkill’... The rule of thumb
is: Brainstorm many possible algorithms - then pick the simplest that works (fast enough to
pass the time and memory limit, yet still produce the correct answer)3 !
For example, the maximum size of input n is 100K, or 105 (1K = 1, 000), and your algorithm
has time complexity of order O(n2 ). Your common sense tells you that (100K)2 is an extremely big
number, it is 1010 . So, you will try to devise a faster (and correct) algorithm to solve the problem,
say of order O(n log2 n). Now 105 log2 105 is just 1.7 × 106 . Since computer nowadays are quite fast
and can process up to ≈ 1M , or 106 (1M = 1, 000, 000) operations in one second, your common
sense tells you that this one is likely able to pass the time limit.
3
Discussion: It is true that in programming contests, picking the simplest algorithm that works is crucial. However,
during training sessions, where we are not under time constraint, it is beneficial if we spent more time trying to solve
a certain problem using the best possible algorithm, because maybe in the future contests, we meet a harder version
of the problem. If we are well prepared, the chance that we can come up with the correct solution is higher.

5
1.2. TIPS TO BE COMPETITIVE 
c Steven & Felix

Now how about this scenario: You can only devise an algorithm of order O(n4 ). Seems pretty
bad right? But if n ≤ 10, then you are done. Just directly implement your O(n4 ) algorithm since
104 is just 10K and your algorithm will only use a relatively small computation time.
So, by analyzing the complexity of your algorithm with the given input bound and stated
time/memory limit, you can judge whether you should try coding your algorithm (which will take
your time, especially in the time-constrained ICPCs and IOIs), attempt to improve your algorithm
first, or switch to other problems in the problem set.
In this book, we will not discuss the concept of algorithm analysis in details. We assume that
you already have this basic skill. Please check other reference books (for example, the “Introduction
to Algorithms” [3], “Algorithm Design” [23], etc) and make sure that you understand how to:

• Prove the correctness of an algorithm (especially for Greedy algorithms in Section 3.4).

• Analyze time/space complexity for iterative and recursive algorithms.

• Perform amortized analysis (see [3], Chapter 17) – although rarely used in contests.

• Do output-sensitive analysis, to analyze algorithm which depends on output size. Example:


The O(m + occ) complexity to find a pattern string with length m in a long string with
length n with the help of Suffix Tree (see Section 6.6.3). See that the time complexity does
not depend on the input size n but on the output size m and number of occ(urences).

Many novice programmers would skip this phase and attempt to directly code the first algorithm
that they can think of (usually the naı̈ve version) only to realize that the chosen data structure is
not efficient or their algorithm is not fast enough (or wrong). Our advice for ICPC contestants4 :
Refrain from coding until you are sure that your algorithm is both correct and fast enough.
To help you in judging how fast is ‘enough’, we produce Table 1.4. Variants of such Table 1.4
can also be found in many algorithms book. However, we put another one here from a programming
contest’s perspective. Usually, the input size constraints are given in (good) problem description.
Using some logical assumptions that typical year 2011 CPU can do 1M operations in 1s and time
limit of 3s (typical time limit used in most UVa online judge [28] problems), we can predict the
‘worst’ algorithm that can still pass the time limit. Usually, the simplest algorithm has poor time
complexity, but if it can pass the time limit, just use it!

n Worst AC Algorithm Comment


≤ 10 O(n!), O(n6 ) e.g. Enumerating a permutation (Section 3.2)
≤ 15 O(2n × n2 ) e.g. DP TSP (Section 3.5.2)
≤ 20 O(2n ), O(n5 ) e.g. DP + bitmask technique (Section 8.4.1)
≤ 50 O(n4 ) e.g. DP with 3 dimensions + O(n) loop, choosing n Ck=4
≤ 100 O(n3 ) e.g. Floyd Warshall’s (Section 4.5)
≤ 1K O(n2 ) e.g. Bubble/Selection/Insertion Sort (Section 2.2.1)
≤ 100K O(n log2 n) e.g. Merge Sort, building Segment Tree (Section 2.2.2)
≤ 1M O(n), O(log 2 n), O(1) Usually, contest problem has n ≤ 1M (e.g. to read input)

Table 1.4: Rule of Thumb for the ‘Worst AC Algorithm’ for various input size n (single test case
only), assuming that year 2011 CPU can compute 1M items in 1s and Time Limit of 3s.

From Table 1.4, we see the importance of knowing good algorithms with lower order of growth as
they allow us to solve problems with bigger input size. Beware that a faster algorithm is usually
non trivial and harder to code. In Section 3.2.2 later, we will see a few tips that may allow us to
enlarge the possible input size n for the same class of algorithm. In the other chapters in this book,
we will see efficient algorithms for various computing problems.
4
Discussion: Unlike ICPC, the tasks presented in IOI usually can be solved with several possible solutions with
different efficiency and thus different scoring criteria. To gain valuable points, it may be beneficial to initially use a
brute force solution to score few points and to understand the problem better. There are no significant time penalty
as IOI is not a speed contest. Then, iteratively improve the solution to gain more points.

6
1.2. TIPS TO BE COMPETITIVE 
c Steven & Felix

Additionally, we have a few other rules of thumb that are useful in programming contests:

• 210 = 1, 024 ≈ 103 , 220 = 1, 048, 576 ≈ 106 .

• Max 32-bit signed integer: 231 − 1 ≈ 2 × 109 (safe for up to ≈ 9 decimal digits);
Max 64-bit signed integer (long long) is 263 − 1 ≈ 9 × 1018 (safe for up to ≈ 18 decimal digits).
Use ‘unsigned’ if slightly higher positive number is needed [0..264 − 1].
If you need to store integers ≥ 264 , you need to use the Big Integer technique (Section 5.3).

• Program with nested loops of depth k running about n iterations each has O(nk ) complexity.

• If your program is recursive with b recursive calls per level and has L levels, the program has
roughly O(bL ) complexity. But this is an upper bound. The actual complexity depends on
what actions done per level and whether some pruning are possible.

• There are n! permutations and 2n subsets (or combinations) of n elements.

• Dynamic Programming algorithms which fill in a 2D matrix in O(k) per cell is in O(k × n2 ).
More details in Section 3.5 later.

• The best time complexity of a comparison-based sorting algorithm is Ω(n log2 n).

• Most of the time, O(n log2 n) algorithms will be sufficient for most contest problems.

• The largest input size for typical programming contest problems must be << 1M , because
beyond that, the time needed to read the input (the I/O routine) will be the bottleneck.

Exercise 1.2.2: Please answer the following questions below using your current knowledge about
classic algorithms and their time complexities. After you have finished reading this book once, it
may be beneficial to re-attempt this exercise again.

1. There are n webpages (1 ≤ n ≤ 10M ). Each webpage i has different page rank ri . You want
to pick the top 10 pages with highest page ranks. Which method is more feasible?

(a) Load all n webpages’ page rank to memory, sort (Section 2.2.1), and pick the top 10.
(b) Use priority queue data structure (heap) (Section 2.2.2).

2. Given a list L of up to 10K integers. You need to frequently ask the value of sum(i, j), i.e.
the sum of L[i] + L[i+1] + ...+ L[j]. Which data structure should you use?

(a) Simple Array (Section 2.2.1).


(b) Simple Array that is pre-processed with Dynamic Programming (Section 2.2.1 & 3.5).
(c) Balanced Binary Search Tree (Section 2.2.2).
(d) Hash Table (Section 2.2.2).
(e) Segment Tree (Section 2.3.3).
(f) Fenwick Tree (Section 2.3.4).
(g) Suffix Tree (Section 6.6.2).
(h) Suffix Array (Section 6.6.4).

3. Given a set S of N points randomly scattered on 2D plane, N ≤ 1000. Find two points ∈ S
that has the greatest Euclidian distance. Is O(N 2 ) complete search algorithm that try all
possible pairs feasible?

(a) Yes, such complete search is possible.


(b) No, we must find another way.

7
1.2. TIPS TO BE COMPETITIVE 
c Steven & Felix

4. You have to compute the ‘shortest path’ between two vertices on a weighted Directed Acyclic
Graph (DAG) with |V |, |E| ≤ 100K. Which algorithm(s) can be used in contest setting?

(a) Dynamic Programming (Section 3.5, 4.2.5, & 4.7.1).


(b) Breadth First Search (Section 4.2.2 & 4.4.2).
(c) Dijkstra’s (Section 4.4.3).
(d) Bellman Ford’s (Section 4.4.4).
(e) Floyd Warshall’s (Section 4.5).

5. Which algorithm is faster (based on its time complexity) for producing a list of the first 10K
prime numbers? (Section 5.5.1)

(a) Sieve of Eratosthenes (Section 5.5.1).


(b) For each number i ∈ [1..10K], test if isPrime(i) is true (Section 5.5.1).

6. You want to test if factorial of n, i.e. n! is divisible by an integer m. 1 ≤ n ≤ 10000.


What should you do?

(a) Test if n! % m == 0.
(b) The naı̈ve approach above will not work. We must use: (Section 5.5.1).

7. You want to know all the occurrences of a substring P (of length m) in a (long) string T (of
length n), if any. Both n and m can go up to 1M characters.

(a) Use the following C++ code snippet:

for (int i = 0; i < n; i++) {


bool found = true;
for (int j = 0; j < m && found; j++)
if (P[j] != T[i + j]) found = false;
if (found) printf("P = %s is found in index %d in T\n", P, i);
}

(b) The naı̈ve approach above will not work. We must use: (Section 6.4).

8. Same problem as in question 3 earlier, but now the number of points N is larger: N ≤ 1M .
Recall that the points are randomly scattered on 2D plane.

(a) The complete search mentioned in question 3 can still be used.


(b) The naı̈ve approach above will not work. We must use: (Section 7.3.7).

1.2.3 Tip 4: Master Programming Languages


There are several programming languages allowed in ICPC5 , including C/C++ and Java.
Which one should we master?
Our experience gave us this answer: Although we prefer C++ with built-in Standard Tem-
plate Library (STL), we still need to master Java, albeit slower, since Java has powerful BigInte-
ger/BigDecimal, String Processing, GregorianCalendar API, etc. Java is more debugging friendly
as a Java program displays its ‘stack trace’ when it ‘crash’ (as opposed to C/C++ ‘core dump’).
5
Important note: Looking at the IOI 2011 competition rules, Java is currently still not allowed in IOI. The
programming languages allowed in IOI are C, C++, and Pascal. On the other hand, ICPC World Finals (and thus
most Regionals) allows C, C++ and Java. Looking at this situation, it is seems that the ‘best’ language to master
is C++ as it is allowed in both competitions and it has strong STL support.

8
1.2. TIPS TO BE COMPETITIVE 
c Steven & Felix

A simple illustration is shown below (this is part of the solution for UVa problem 623: 500!):
Compute 25! (factorial of 25). The answer is very large: 15,511,210,043,330,985,984,000,000. This
is way beyond the largest built-in integer data type (unsigned long long: 264 − 1) in C/C++.
Using C/C++, you will have hard time coding this simple problem as there is no native support
for BigInteger data structure in C/C++ yet. Meanwhile, the Java code is simply this:

import java.util.Scanner;
import java.math.BigInteger;

class Main { // standard Java class name in UVa OJ


public static void main(String[] args) {
BigInteger fac = BigInteger.ONE; // :)
for (int i = 2; i <= 25; i++)
fac = fac.multiply(BigInteger.valueOf(i)); // wow :)
System.out.println(fac);
} }

Another illustration to further demonstrate that mastering a programming language is important:


Please read this input: The first line of input is an integer N . Then, there are N lines that start
with the character ‘0’, followed by one dot ‘.’, followed by an unknown number of digits (up to 100
digits), and finally terminated with three dots ‘...’. See the example below.

3
0.1227...
0.517611738...
0.7341231223444344389923899277...

One solution is as follows:

#include <cstdio>
using namespace std;

int N; // using global variables in contests can be a good strategy


char x[110]; // make it a habit to set array size slightly larger than needed

int main() {
scanf("%d", &N);
while (N--) { // we simply loop from N, N-1, N-2, ... 0
scanf("0.%[0-9]...", &x); // if you are surprised with this line,
// check scanf details in www.cppreference.com
printf("the digits are 0.%s\n", x);
}
return 0;
}

Example codes: ch1 01 factorial.java; ch1 02 scanf.cpp

Not many C/C++ programmers are aware of the trick above. Although scanf/printf are C-style
I/O routines, they can still be used in a C++ code. Many C++ programmers ‘force’ themselves to
use cin/cout all the time which, in our opinion, are not as flexible as scanf/printf and slower.
In programming contests, especially ICPCs, coding should not be your bottleneck at all. That
is, once you figure out the ‘worst AC algorithm’ that will pass the given time limit, you are supposed
to be able to translate it into a bug-free code and you can do it fast!
Now, try to do some exercises below! If you need more than 10 lines of code to solve them, you
will need to relearn your programming language(s) in depth! Mastery of programming language
routines will help you a lot in programming contests.

9
1.2. TIPS TO BE COMPETITIVE 
c Steven & Felix

Exercise 1.2.3: Write the shortest codes that you can think of for the following tasks:
1. Given a string that represents a base X number, convert it to equivalent string in base Y,
2 ≤ X, Y ≤ 36. For example: “FF” in base X = 16 (Hexadecimal) is “255” in base Y1 = 10
(Decimal) and “11111111” in base Y2 = 2 (binary). (More details in Section 5.3.2).
2. Given a list of integers L of size up to 1M items, determine whether a value v exists in L by
not using more than 20 comparisons? (More details in Section 2.2.1).
3. Given a date, determine what is the day (Monday, Tuesday, . . . , Sunday) of that date?
(e.g. 9 August 2010 – the launch date of the first edition of this book – is Monday).
4. Given a string, replace all ‘special words’ of length 3 with 3 stars “***”. The ‘special word’
starts with a lowercase alphabet character and followed by two consecutive digits, e.g.
S = “line: a70 and z72 will be replaced, but aa24 and a872 will not”
will be transformed to
S = “line: *** and *** will be replaced, but aa24 and a872 will not”.
5. Write the shortest possible Java code to read in a double
(e.g. 1.4732, 15.324547327, etc)
and print it again, but now with minimum field width 7 and 3 digits after decimal point
(e.g. ss1.473 (where ‘s’ denotes a space), s15.325, etc)
6. Generate all possible permutations of {0, 1, 2, . . . , N-1}, for N = 10.
7. Generate all possible subsets of {0, 1, 2, . . . , N-1}, for N = 20.

1.2.4 Tip 5: Master the Art of Testing Code


You thought that you have nailed a particular problem. You have identified its type, designed the
algorithm for it, calculated the algorithm’s time/space complexity - it will be within the time and
memory limit given, and coded the algorithm. But, your solution is still not Accepted (AC).
Depending on the programming contest’s type, you may or may not get credit by solving the
problem partially. In ICPC, you will only get credit if your team’s code solve all the judge’s secret
test cases, that’s it, you get AC. Other responses like Presentation Error (PE), Wrong Answer
(WA), Time Limit Exceeded (TLE), Memory Limit Exceeded (MLE), Run Time Error (RTE), etc
do not increase your team’s points. In IOI (2010-2011), the subtask scoring system is used. Test
cases are grouped into subtasks, usually the simpler variants of the original task. You will only get
the score of a subtask if your code solves all test cases that belong to that subtask. You are given
tokens that you can use sparsely throughout the contest to see the judging result of your code.
In either case, you will need to be able to design good, educated, tricky test cases. The sample
input-output given in problem description is by default too trivial and therefore not a good way
for measuring the correctness of your code.
Rather than wasting submissions (and get time or point penalties) in ICPC or tokens in IOI
by getting non AC responses, you may want to design some tricky test cases first, test it in your
own machine, and ensure that your code is able to solve it correctly (otherwise, there is no point
submitting your solution right?).
Some coaches ask their students to compete with each other by designing test cases. If student
A’s test cases can break other student’s code, then A will get bonus point. You may want to try
this in your team training too :).
Here are some guidelines for designing good test cases, based on our experience:
These are the typical steps taken by the problem setters too.
1. Your test cases must include the sample input as you already have the answer given.
Use fc in Windows or diff in UNIX to check your code’s output against the sample output.
Avoid manual comparison as we are not good in performing such task, especially for problems
with delicate output format.

10
1.2. TIPS TO BE COMPETITIVE 
c Steven & Felix

2. For multiple input test cases, you should include two identical sample test cases consecutively.
Both must output the same known correct results.
This is to check whether you have forgotten to initialize some variables, which will be easily
identified if the 1st instance produces the correct output but the 2nd one does not.
3. Your test cases must include large cases.
Increase the input size incrementally up to the maximum possible stated in problem descrip-
tion. Sometimes your program works for small input size, but behave wrongly (or slowly)
when input size increases. Check for overflow, out of bounds, etc if that happens.
4. Your test cases must include the tricky corner cases.
Think like the problem setter! Identify cases that are ‘hidden’ in the problem description.
Some typical corner cases: N = 0, N = 1, N = maximum values allowed in problem description,
N = negative values, etc. Think of the worst possible input for your algorithm.
5. Do not assume the input will always be nicely formatted if the problem description does not
say so (especially for a badly written problem). Try inserting white spaces (spaces, tabs) in
your input, and check whether your code is able to read in the values correctly (or crash).
6. Finally, generate large random test cases to see if your code terminates on time and still give
reasonably ok output (the correctness is hard to verify here – this test is only to verify that
your code runs within the time limit).
However, after all these careful steps, you may still get non-AC responses. In ICPC6 , you and your
team can actually use the judge’s response to determine your next action. With more experience
in such contests, you will be able to make better judgment. See the next exercises:
Exercise 1.2.4: Situation judging (Mostly in ICPC setting. This is not so relevant in IOI).
1. You receive a WA response for a very easy problem. What should you do?

(a) Abandon this problem and do another.


(b) Improve the performance of your solution (optimize the code or use better algorithm).
(c) Create tricky test cases and find the bug.
(d) (In team contest): Ask another coder in your team to re-do this problem.

2. You receive a TLE response for an your O(N 3 ) solution. However, maximum N is just 100.
What should you do?

(a) Abandon this problem and do another.


(b) Improve the performance of your solution (optimize the code or use better algorithm).
(c) Create tricky test cases and find the bug.

3. Follow up question (see question 2 above): What if maximum N is 100.000?


4. You receive an RTE response. Your code runs OK in your machine. What should you do?
5. One hour to go before the end of the contest. You have 1 WA code and 1 fresh idea for
another problem. What should you (your team) do?

(a) Abandon the problem with WA code, switch to that other problem in attempt to solve
one more problem.
(b) Insist that you have to debug the WA code. There is not enough time to start working
on a new code.
(c) (In ICPC): Print the WA code. Ask two other team members to scrutinize the code
while you switch to that other problem in attempt to solve two more problems.
6
In IOI 2010-2011, contestants have limited tokens that they can use sparingly to check the correctness of their
submitted code. The exercise in this section is more towards ICPC style contest.

11
1.2. TIPS TO BE COMPETITIVE 
c Steven & Felix

1.2.5 Tip 6: Practice and More Practice


Competitive programmers, like real athletes, must train themselves regularly and keep themselves
‘programming-fit’. Thus in our last tip, we give a list of some websites that can help to improve
your problem solving skill. Success comes as a result of a continuous journey to better yourself.
University of Valladolid (from Spain) Online Judge [28] contains past years ACM contest prob-
lems (usually local or regional) plus problems from other sources, including their own contest
problems. You can solve these problems and submit your solutions to this Online Judge. The
correctness of your program will be reported as soon as possible. Try solving the problems men-
tioned in this book and see your name on the top-500 authors rank list someday :-). At the point
of writing (1 August 2011), Steven is ranked 64 (for solving 1180 problems) while Felix is ranked
54 (for solving 1239 problems) from ≈ 115266 UVa users and ≈ 2950 problems.
UVa’s ‘sister’ online judge is the ACM ICPC Live Archive [20] that contains almost all recent
ACM ICPC Regionals and World Finals problem sets since year 2000. Train here if you want to
do well in future ICPCs.

Figure 1.2: Left: University of Valladolid (UVa) Online Judge; Right: ACM ICPC Live Archive.

USA Computing Olympiad has a very useful training website [29] and online contests for you to
learn programming and problem solving. This one is geared more towards IOI participants. Go
straight to their website, register your account, and train yourself.
Sphere Online Judge [35] is another online judge where qualified users can add problems too.
This online judge is quite popular in countries like Poland, Brazil, and Vietnam. We use this SPOJ
to publish some of our self-authored problems.

Figure 1.3: Left: USACO Training Gateway; Right: Sphere Online Judge

TopCoder arranges frequent ‘Single Round Match’ (SRM) [19] that consists of a few problems that
should be solved in 1-2 hours. Afterwards, you are given the chance to ‘challenge’ other contestants
code by supplying tricky test cases. This online judge uses a rating system (red, yellow, blue, etc
coders) to reward contestants who are really good in problem solving with higher rating as opposed
to more diligent contestants who happen to solve ‘more’ easier problems.

1.2.6 Tip 7: Team Work (ICPC Only)


This last tip is not something that is teachable. But here are some ideas that may be worth trying:

• Practice coding on a blank paper (useful when your teammate is using the computer).

• Submit and print strategy. If your code is AC, ignore your printout. If it is still not AC,
debug using that printout (and let your teammate use the computer for other problem).

• If your teammate is currently coding his algorithm, prepare challenges for his code by prepar-
ing hard corner test cases (and hopefully his code passes all those).

• The X-factor: Befriend your teammates outside the training sessions & actual competition.

12
1.3. GETTING STARTED: THE AD HOC PROBLEMS 
c Steven & Felix

1.3 Getting Started: The Ad Hoc Problems


We end this chapter by asking you to start with the first problem type in ICPCs and IOIs: the Ad
Hoc problems. According to USACO [29], Ad Hoc problems are problems that ‘cannot be classified
anywhere else’, where each problem description and its corresponding solution are ‘unique’.
Ad Hoc problems almost always appear in a programming contest. Using a benchmark of total
10 problems, there may be 1-2 Ad Hoc problems in an ICPC. If the Ad Hoc problem is easy, it will
usually be the first problem solved by the teams in a programming contest. But there exists Ad
Hoc problems that are complicated to code and some teams will strategically defer solving them
until the last hour. Assuming a 60-teams contest, your team is probably in the lower half (rank
30-60) if your team can only do this type of problem during an ICPC regional contest.
In IOI 2009 and 2010, there exists 1 easy task per competition day7 , which is usually an Ad Hoc
task. If you are an IOI contestant, you will definitely not going to get any medal by only solving
these 2 easy Ad Hoc tasks over 2 competition days. However, the faster you can clear these 2 easy
tasks, the more time that you will have to work on the other 2 × 3 = 6 challenging tasks.
To help you pick which problems to start with among the ≈ 2950 problems in UVa online judge
[28] (and some other online judges), we have listed many Ad Hoc problems that we have solved
into several sub-categories below. Each category still contains a lot of problems, so we highlight
up to maximum three (3) must try * problems in each category. These are the problems that we
think are more interesting or have better quality.
We believe that you can solve most of these problems without using advanced data structures
or algorithms that will be discussed in the latter chapters. Many of these Ad Hoc problems are
‘simple’ but some of them maybe ‘tricky’. Now, try to solve few problems from each category before
reading the next chapter.
The categories:

• (Super) Easy
You should get these problems AC8 in under 7 minutes each!
If you are new with competitive programming, we strongly recommend that you start your
journey by solving some problems from this category.
• Game (Card)
There are lots of Ad Hoc problems involving popular games. The first game type is re-
lated to cards. Usually you will need to parse the string input as normal cards have suits
(D/Diamond/♦, C/Club/♣, H/Heart/♥, and S/Spades/♠) on top of the ranks (usually: 2
< 3 < . . . < 9 < T/Ten < J/Jack < Q/Queen < K/King < A/Ace9 ). It may be a good idea
to map these complicated strings to integer indices. For example, one possible mapping is to
map D2 → 0, D3 → 1, . . . , DA → 12, C2 → 13, C3 → 14, . . . , SA → 51. Then, we work
with the integer indices instead.
• Game (Chess)
Another popular games that sometimes appear in programming contest problems are chess
problems. Some of them are Ad Hoc (listed in this section). Some of them are combinatorial,
like counting how many ways to put 8-queens in 8 × 8 chess board (listed in Chapter 3).
• Game (Others)
Other than card and chess games, there are many other popular problems related to other
games that make their way into programming contest problems: Tic Tac Toe, Rock-Paper-
Scissors, Snakes/Ladders, BINGO, Bowling, and several others. Knowing the details of the
game is helpful, but most of the game rules are given in the problem description to avoid
disadvantaging contestants who have not played those games before.
7
This is no longer true in IOI 2011.
8
However, do not feel bad if you fail to do so. There are reasons why a code does not get AC response. Once you
are more familiar with competitive programming, you will find that these problems are indeed super easy.
9
In some other arrangement, A/Ace < 2.

13
1.3. GETTING STARTED: THE AD HOC PROBLEMS 
c Steven & Felix

• The ‘Josephus’-type problems


The Josephus problem is a classic problem where there are n people numbered from 1, 2, . . . ,
n, standing in a circle. Every m-th person is going to be executed. Only the last remaining
person will be saved (history said it was the person named Josephus). The smaller version of
this problem can be solved with plain brute force. The larger ones require better solutions.

• Problems related to Palindrome or Anagram


These are also classic problems.
Palindrome is a word (or actually a sequence) that can be read the same way in either
direction. The common strategy to check if a word is palindrome is to loop from the first
character to the middle one and check if the first match the last, the second match the second
last, and so on. Example: ‘ABCDCBA’ is a palindrome.
Anagram is a rearrangement of letters of a word (or phrase) to get another word (or phrase)
using all the original letters. The common strategy to check if two words are anagram is to
sort the letters of the words and compare the sorted letters. Example: wordA = ‘cab’, wordB
= ‘bca’. After sorting, wordA = ‘abc’ and wordB = ‘abc’ too, so they are anagram.

• Interesting Real Life Problems


This is one of the most interesting category of problems in UVa online judge. We believe that
real life problems like these are interesting to those who are new to Computer Science. The
fact that we write programs to solve real problems is an extra motivation boost. Who knows
you may also learn some new interesting knowledge from the problem description!

• Ad Hoc problems involving Time


Date, time, calendar, . . . . All these are also real life problems. As said earlier, people usually
get extra motivation when dealing with real life problems. Some of these problems will be
much easier to solve if you have mastered the Java GregorianCalendar class as it has lots of
library functions to deal with time.

• Just Ad Hoc
Even after our efforts to sub-categorize the Ad Hoc problems, there are still many others that
are too Ad Hoc to be given a specific sub-category. The problems listed in this sub-category
are such problems. The solution for most problems is to simply follow/simulate the problem
description carefully.

• Ad Hoc problems in other chapters


There are many other Ad Hoc problems which we spread to other chapters, especially because
they require some more knowledge on top of basic programming skills.

– Ad Hoc problems involving the usage of basic linear data structures, especially arrays
are listed in Section 2.2.1.
– Ad Hoc problems involving mathematical computations are listed in Section 5.2.
– Ad Hoc problems involving processing of strings are listed in Section 6.3.
– Ad Hoc problems involving basic geometry skills are listed in Section 7.2.

Tips: After solving some number of programming problems, you will encounter some pattern.
From a C/C++ perspective, those pattern are: libraries to be included (cstdio, cmath, cstring,
etc), data type shortcuts (ii, vii, vi, etc), basic I/O routines (freopen, multiple input format,
etc), loop macros (e.g. #define REP(i, a, b) for (int i = int(a); i <= int(b); i++),
etc), and a few others. A competitive programmer using C/C++ can store all those in a header
file ‘competitive.h’. Now, every time he wants to solve another problem, he just need to open a
new *.c or *.cpp file, and type #include<competitive.h>.

14
1.3. GETTING STARTED: THE AD HOC PROBLEMS 
c Steven & Felix

Programming Exercises related to Ad Hoc problems:

• Easy Problems in UVa Online Judge (under 7 minutes)


1. UVa 00272 - TEX Quotes (simply replace all double quotes to TEX() style quotes)
2. UVa 00494 - Kindergarten Counting Game (count frequency of words in a line10 )
3. UVa 00499 - What’s The Frequency ... (ad hoc, 1D array manipulation)
4. UVa 10300 - Ecological Premium (straightforward, ignore ‘total animal’)
5. UVa 10420 - List of Conquests * (simple frequency counting, use map)
6. UVa 10550 - Combination Lock (simple, do as asked)
7. UVa 11044 - Searching for Nessy (one liner code/formula exists)
8. UVa 11172 - Relational Operators (ad hoc, very easy, one liner)
9. UVa 11332 - Summing Digits (simple recursions, O(1) solution exists (modulo 9))
10. UVa 11498 - Division of Nlogonia (straightforward problem; use one if-else statement)
11. UVa 11547 - Automatic Answer (one liner O(1) solution exists)
12. UVa 11559 - Event Planning * (answer can be found by reading input data once)
13. UVa 11727 - Cost Cutting (sort the 3 numbers and get the median)
14. UVa 11764 - Jumping Mario (one linear scan to count high and low jumps)
15. UVa 11799 - Horror Dash * (one linear scan to find the max value)
16. UVa 11942 - Lumberjack Sequencing (check if input is sorted ascending/descending)
17. UVa 12015 - Google is Feeling Lucky (go through the list twice: get max, print max)
• Game (Card)
1. UVa 00162 - Beggar My Neighbour (card game simulation, straightforward)
2. UVa 00462 - Bridge Hand Evaluator * (simulation, card)
3. UVa 00555 - Bridge Hands (card)
4. UVa 10205 - Stack ’em Up * (card game)
5. UVa 10646 - What is the Card? * (shuffle cards with some rule; get certain card)
6. UVa 11225 - Tarot scores (another card game)
7. UVa 11678 - Card’s Exchange (actually just array manipulation problem)
• Game (Chess)
1. UVa 00255 - Correct Move (check the validity of chess moves)
2. UVa 00278 - Chess * (ad hoc, chess, closed form formula exists)
3. UVa 00696 - How Many Knights * (ad hoc, chess)
4. UVa 10196 - Check The Check (ad hoc chess game, tedious)
5. UVa 10284 - Chessboard in FEN * (FEN = Forsyth-Edwards Notation)
6. UVa 10849 - Move the bishop (chess)
7. UVa 11494 - Queen (ad hoc, chess)
• Game (Others)
1. UVa 00220 - Othello (follow the game rules, a bit tedious)
2. UVa 00227 - Puzzle (parse the input, array manipulation)
3. UVa 00232 - Crossword Answers (another complex array manipulation problem)
4. UVa 00339 - SameGame Simulation (follow problem description)
5. UVa 00340 - Master-Mind Hints (determine strong and weak matches)
6. UVa 00489 - Hangman Judge (just do as asked)
7. UVa 00584 - Bowling * (simulation, games, test your reading comprehension)
8. UVa 00647 - Chutes and Ladders (child board game, similar to UVa 11459)
9. UVa 10189 - Minesweeper * (simulate Minesweeper game, similar to UVa 10279)
10. UVa 10279 - Mine Sweeper (2D array helps, similar to UVa 10189)
11. UVa 10363 - Tic Tac Toe (check validity of Tic Tac Toe game, tricky)
10
Delimiter are the non-alphabetical characters. Can be solved ‘elegantly’ with Java Regular Expression.

15
1.3. GETTING STARTED: THE AD HOC PROBLEMS 
c Steven & Felix

12. UVa 10409 - Die Game (just simulate the die movement)
13. UVa 10443 - Rock, Scissors, Paper (2D arrays manipulation)
14. UVa 10530 - Guessing Game (use 1D flag array)
15. UVa 10813 - Traditional BINGO (follow the problem description)
16. UVa 10903 - Rock-Paper-Scissors ... (count win+losses, output win average)
17. UVa 11459 - Snakes and Ladders * (simulate the process, similar to UVa 647)
• Josephus
1. UVa 00130 - Roman Roulette (brute force, similar to UVa 133)
2. UVa 00133 - The Dole Queue (brute force, similar to UVa 130)
3. UVa 00151 - Power Crisis * (brute force, similar to UVa 440)
4. UVa 00305 - Joseph * (the answer can be precalculated)
5. UVa 00402 - M*A*S*H (simulation problem)
6. UVa 00440 - Eeny Meeny Moo (brute force, similar to UVa 151)
7. UVa 10015 - Joseph’s Cousin * (modified Josephus problem, variant of UVa 305)
• Palindrome / Anagram
1. UVa 00148 - Anagram Checker (uses backtracking)
2. UVa 00156 - Ananagram * (easier with algorithm::sort)
3. UVa 00195 - Anagram * (easier with algorithm::next permutation)
4. UVa 00353 - Pesky Palindromes (brute force all substring)
5. UVa 00401 - Palindromes (simple palindrome check)
6. UVa 00454 - Anagrams (anagram)
7. UVa 00630 - Anagrams (II) (ad hoc, string)
8. UVa 10018 - Reverse and Add (ad hoc, math, palindrome check)
9. UVa 10098 - Generating Fast, Sorted ... (very similar to UVa 195)
10. UVa 10945 - Mother Bear (palindrome)
11. UVa 11221 - Magic Square Palindrome * (not just a word, but a matrix)
12. UVa 11309 - Counting Chaos (palindrome check)
• Interesting Real Life Problems
1. UVa 00161 - Traffic Lights * (you see this problem every time you hit the road)
2. UVa 00346 - Getting Chorded (musical chord, major/minor)
3. UVa 00400 - Unix ls (this command is very popular among UNIX users)
4. UVa 00403 - Postscript (emulation of printer driver)
5. UVa 00448 - OOPS (tedious ‘hexadecimal’ to ‘assembly language’ conversion)
6. UVa 00538 - Balancing Bank Accounts (the story in the problem really happens)
7. UVa 00637 - Booklet Printing * (application in printer driver software)
8. UVa 00706 - LC-Display (this is what we typically see in old computer monitors)
9. UVa 10082 - WERTYU (this keyboard typing error happens to us sometimes)
10. UVa 10191 - Longest Nap (you may want to apply this for your own schedule)
11. UVa 10415 - Eb Alto Saxophone Player (a problem about musical instrument)
12. UVa 10528 - Major Scales (the music knowledge is given in the problem description)
13. UVa 10554 - Calories from Fat (for those who are concerned with their weights)
14. UVa 10659 - Fitting Text into Slides (typical presentation programs do this)
15. UVa 10812 - Beat the Spread * (be careful with boundary cases!)
16. UVa 11223 - O: dah, dah, dah (tedious morse code conversion problem)
17. UVa 11530 - SMS Typing (many handphone users encounter this problem everyday)
18. UVa 11743 - Credit Check (Luhn’s algorithm to check credit card number)
19. UVa 11984 - A Change in Thermal Unit (F◦ to C◦ conversion and vice versa)
• Time
1. UVa 00170 - Clock Patience (simulation, time)
2. UVa 00300 - Maya Calendar (ad hoc, time)
3. UVa 00579 - Clock Hands * (ad hoc, time)

16
1.3. GETTING STARTED: THE AD HOC PROBLEMS 
c Steven & Felix

4. UVa 00837 - Y3K * (use Java GregorianCalendar; similar to UVa 11356)


5. UVa 10070 - Leap Year or Not Leap Year ... (more than just ordinary leap years)
6. UVa 10371 - Time Zones (follow the problem description)
7. UVa 10683 - The decadary watch (simple clock system conversion)
8. UVa 11219 - How old are you? (be careful with boundary cases!)
9. UVa 11356 - Dates (very easy if you use Java GregorianCalendar)
10. UVa 11650 - Mirror Clock (some small mathematics required)
11. UVa 11677 - Alarm Clock (similar idea with UVa 11650)
12. UVa 11947 - Cancer or Scorpio * (much easier with Java GregorianCalendar)
13. UVa 11958 - Coming Home (be careful with ‘past midnight’)
14. UVa 12019 - Doom’s Day Algorithm (Java Gregorian Calendar; get DAY OF WEEK)
• Just Ad Hoc
1. UVa 00101 - The Blocks Problem (simulation)
2. UVa 00114 - Simulation Wizardry (simulation)
3. UVa 00119 - Greedy Gift Givers (simulate give and receive process)
4. UVa 00121 - Pipe Fitters (ad hoc)
5. UVa 00139 - Telephone Tangles (adhoc string, simulation)
6. UVa 00141 - The Spot Game (simulation)
7. UVa 00144 - Student Grants (simulation)
8. UVa 00145 - Gondwanaland Telecom (simply calculate the charges)
9. UVa 00187 - Transaction Processing (simulation)
10. UVa 00335 - Processing MX Records (simulation)
11. UVa 00337 - Interpreting Control Sequences (simulation, output related)
12. UVa 00349 - Transferable Voting (II) (simulation)
13. UVa 00362 - 18,000 Seconds Remaining (simulation)
14. UVa 00379 - HI-Q (simulation)
15. UVa 00381 - Making the Grade (simulation)
16. UVa 00405 - Message Routing (simulation)
17. UVa 00434 - Matty’s Blocks (ad hoc)
18. UVa 00457 - Linear Cellular Automata (simulation)
19. UVa 00496 - Simply Subsets (ad hoc, set manipulation)
20. UVa 00556 - Amazing * (simulation)
21. UVa 00573 - The Snail (simulation, beware of boundary cases!)
22. UVa 00608 - Counterfeit Dollar (ad hoc)
23. UVa 00621 - Secret Research (case analysis for 4 possible outputs)
24. UVa 00661 - Blowing Fuses (simulation)
25. UVa 00978 - Lemmings Battle * (simulation, use multiset)
26. UVa 10019 - Funny Encryption Method (not hard, find the pattern)
27. UVa 10033 - Interpreter (adhoc, simulation)
28. UVa 10114 - Loansome Car Buyer * (simulate loan payment+car depreciation)
29. UVa 10141 - Request for Proposal (this problem can be solved with one linear scan)
30. UVa 10142 - Australian Voting (simulation)
31. UVa 10188 - Automated Judge Script (simulation)
32. UVa 10267 - Graphical Editor (simulation)
33. UVa 10324 - Zeros and Ones (simplified using 1D array: change counter)
34. UVa 10424 - Love Calculator (just do as asked)
35. UVa 10707 - 2D - Nim (check graph isomorphism, a bit hard)
36. UVa 10865 - Brownie Points (simulation)
37. UVa 10919 - Prerequisites? (process the requirements as the input is read)
38. UVa 10963 - The Swallowing Ground (not hard)
39. UVa 11140 - Little Ali’s Little Brother (ad hoc)
40. UVa 11507 - Bender B. Rodriguez Problem (simulation)

17
1.3. GETTING STARTED: THE AD HOC PROBLEMS 
c Steven & Felix

41. UVa 11586 - Train Tracks (TLE if brute force, find the pattern)
42. UVa 11661 - Burger Time? (linear scan)
43. UVa 11679 - Sub-prime (check if after simulation all banks still have ≥ 0 reserve)
44. UVa 11687 - Digits (simulation, straightforward)
45. UVa 11717 - Energy Saving Microcontroller (tricky simulation)
46. UVa 11850 - Alaska (ad hoc)
47. UVa 11917 - Do Your Own Homework (ad hoc)
48. UVa 11946 - Code Number (ad hoc)
49. UVa 11956 - Brain**** (simulation; ignore ‘.’)
50. IOI 2009 - Garage
51. IOI 2009 - POI
52. IOI 2010 - Cluedo (use 3 pointers)
53. IOI 2010 - Memory (use 2 linear pass)
54. LA 2189 - Mobile Casanova (Dhaka06)
55. LA 3012 - All Integer Average (Dhaka04)
56. LA 3996 - Digit Counting (Danang07)
57. LA 4147 - Jollybee Tournament (Jakarta08)
58. LA 4202 - Schedule of a Married Man (Dhaka08)
59. LA 4786 - Barcodes (World Finals Harbin10)
60. LA 4995 - Language Detection (KualaLumpur10)

Figure 1.4: Some references that inspired the authors to write this book

18
1.4. CHAPTER NOTES 
c Steven & Felix

1.4 Chapter Notes


This and subsequent chapters are supported by many text books (see Figure 1.4 in the previous
page) and Internet resources. Here are some additional references:

• To improve your typing skill as mentioned in Tip 1, you may want to play lots of typing
games that are available online.
• Tip 2 is an adaptation from the introduction text in USACO training gateway [29].
• More details about Tip 3 can be found in many CS books, e.g. Chapter 1-5, 17 of [3].
• Online references for Tip 4 are:
http://www.cppreference.com and http://www.sgi.com/tech/stl/ for C++ STL;
http://java.sun.com/javase/6/docs/api for Java API.
• For more insights to do better testing (Tip 5),
a little detour to software engineering books may be worth trying.
• There are many other Online Judges apart from those mentioned in Tip 6, e.g.

– POJ http://acm.pku.edu.cn/JudgeOnline,
– TOJ http://acm.tju.edu.cn/toj,
– ZOJ http://acm.zju.edu.cn/onlinejudge/,
– Ural/Timus OJ http://acm.timus.ru, etc.

• For a note regarding team contest (Tip 7), read [7].

In this chapter, we have introduced the world of competitive programming to you. However, you
cannot say that you are a competitive programmer if you can only solve Ad Hoc problems in every
programming contest. Therefore, we do hope that you enjoy the ride and continue reading and
learning the other chapters of this book, enthusiastically. Once you have finished reading this book,
re-read it one more time. On the second round, attempt the various written exercises and the ≈
1198 programming exercises as many as possible.

There are ≈ 149 UVa (+ 11 others) programming exercises discussed in this chapter.
(Only 34 in the first edition, a 371% increase).
There are 19 pages in this chapter.
(Only 13 in the first edition, a 46% increase).

19
1.4. CHAPTER NOTES 
c Steven & Felix

20
Chapter 2

Data Structures and Libraries

If I have seen further it is only by standing on the shoulders of giants.


— Isaac Newton

2.1 Overview and Motivation


Data structure is ‘a way to store and organize data’ in order to support efficient insertions, searches,
deletions, queries, and/or updates. Although a data structure by itself does not solve the given
programming problem (the algorithm operating on it does), using the most efficient data structure
for the given problem may be the difference between passing or exceeding the problem’s time limit.
There can be many ways to organize the same data and sometimes one way is better than the other
on a different context, as we will see in the discussion below. Familiarity with the data structures
and libraries discussed in this chapter is a must in order to understand the algorithms that use
them in subsequent chapters.
As stated in the preface of this book, we assume that you are familiar with the basic data
structures listed in Section 2.2, and thus we do not review them again in this book. In this book,
we highlight the fact that they all have built-in libraries in C++ STL and Java API1 . Therefore,
if you feel that you are not sure with any of the terms or data structures mentioned in Section
2.2, please pause reading this book, quickly explore and learn that particular term in the reference
books, e.g. [2]2 , and only resume when you get the basic ideas of those data structures.
Note that for competitive programming, you just have to be able to use the correct data
structure to solve the given contest problem. You just have to know the strengths, weaknesses,
and typical time/space complexities of the data structure. Its theoretical background is good to
know, but can be skipped. This is not a good practice but it works. For example, many (younger)
contestants may have used the efficient C++ STL map (in Java: use TreeMap) to store dynamic
collection of key-data pairs without an understanding that the underlying data structure is a
balanced Binary Search Tree – which is typically taught in year 1 Computer Science curriculum.
This chapter is divided into two parts. Section 2.2 contains basic data structures with their
basic operations that already have built-in libraries. The discussion of each data structure in this
section is very brief. Section 2.3 contains more data structures for which currently we have to build
our own libraries. Because of this, Section 2.3 has more detailed discussions than Section 2.2.
The best way to learn the material in this chapter is by examining the example codes. We have
written lots of programming examples in both C++ and Java. The source codes are available in
https://sites.google.com/site/stevenhalim/home/material. The reference to each example
code is indicated the body text as a box like below.
Download codes from https://sites.google.com/site/stevenhalim/home/material

1
In the second edition of this book, we still write most example codes from C++ perspective. However, the Java
version of the C++ codes can be found in the supporting website of this book.
2
Materials in Section 2.2 are usually taught in level-1 ‘data structures and algorithms’ course in CS curriculum.
High school students who are aspiring to take part in the IOI are encouraged to do self-study on these material.

21
2.2. DATA STRUCTURES WITH BUILT-IN LIBRARIES 
c Steven & Felix

2.2 Data Structures with Built-in Libraries


2.2.1 Linear Data Structures
A data structure is classified as linear if its elements form a sequence. Mastery of all these basic
linear data structures below is a must to do well in today’s programming contests.
• Static Array (native support in both C/C++ and Java)
This is clearly the most commonly used data structure in programming contests whenever
there is a collection of sequential data to be stored and later accessed using their indices.
As the maximum input size is typically mentioned in a programming problem, the declared
array size will usually be the value of the given constraint plus a small extra buffer for safety.
Typical array dimensions are: 1D, 2D, and rarely goes beyond 3D. Typical array operations
are: accessing certain indices, sorting, linearly scanning, or binary searching the sorted array.
• Resizeable Array a.k.a. Vector: C++ STL vector (Java ArrayList (faster) or Vector)
Same as static array but has auto-resize feature. It is better to use vector in place of array
if array size is unknown before running the program. Usually, we initialize the size with some
guess value for better performance. Typical operations are: push back(), at(), [] operator,
assign(), clear(), erase(), and using iterator to scan the content of the vector.
Example codes: ch2 01 staticarray stl vector.cpp; ch2 01 staticarray Vector.java

Quick Detour on Efficient Sorting and Searching in Static/Resize-able Array


There are two central operations commonly performed on array: sorting and searching.
It is noteworthy to mention that these two operations are well supported in C++ and Java.
There are many sorting algorithms mentioned in CS textbooks [3, 24, 32] which we classify as:

1. O(n2 ) comparison-based sorting algorithms: Bubble/Selection/Insertion Sort.


These algorithms are slow and usually avoided, but understanding them is important.
2. O(n log n) comparison-based sorting algorithms: Merge/Heap/Random Quick Sort.
We can use sort, partial sort, or stable sort in C++ STL algorithm (Java
Collections.sort) to achieve this purpose. We only need to specify the required
comparison function and these library routines will handle the rest.
3. Special purpose sorting algorithms: O(n) Counting/Radix/Bucket Sort.
These special purpose algorithms are good to know, as they can speed up the sorting time
if the problem has special characteristics, like small range of integers for Counting Sort,
but they rarely appear in programming contests.

There are basically three ways to search for an item in Array which we classify as:

1. O(n) Linear Search from index 0 to index n − 1 (avoid this in programming contests).
2. O(log n) Binary Search: use lower bound in C++ STL algorithm (Java
Collections.binarySearch). If the input is unsorted, it is fruitful to sort it just once
using an O(n log n) sorting algorithm above in order to use Binary Search many times.
3. O(1) with Hashing (but we can live without hashing for most contest problems).

Example codes: ch2 02 stl algorithm.cpp; ch2 02 Collections.java

• Linked List: C++ STL list (Java LinkedList)


Although this data structure almost always appears in data structure & algorithm textbooks,
Linked List is usually avoided in typical contest problems. Reasons: It involves pointers and
slow for accessing data as it has to be performed from the head or tail of a list. In this
book, almost all form of Linked List is replaced by the more flexible C++ STL vector (Java
Vector). The only exception is probably UVa 11988 - Broken Keyboard (a.k.a. Beiju Text).

22
2.2. DATA STRUCTURES WITH BUILT-IN LIBRARIES 
c Steven & Felix

• Stack: C++ STL stack (Java Stack)


This data structure is used as a part of algorithm to solve a certain problem (e.g. Postfix
calculation, bracket matching, Graham’s scan in Section 7.3.7). Stack only allows insertion
(push) and deletion (pop) from the top only. This behavior is called Last In First Out (LIFO)
as with normal stacks in the real world. Typical operations are push()/pop() (insert/remove
from top of stack), top() (obtain content from the top of stack), empty().
• Queue: C++ STL queue (Java Queue3 )
This data structure is used in algorithms like Breadth First Search (BFS) (Section 4.2.2). A
queue only allows insertion (enqueue) from back (tail), and only allows deletion (dequeue)
from front (head). This behavior is called First In First Out (FIFO), similar to normal queues
in the real world. Typical operations are push()/pop() (insert from back/remove from front
of queue), front()/back() (obtain content from the front/back of queue), empty().

Example codes: ch2 03 stl stack queue.cpp; ch2 03 Stack Queue.java

• Lightweight Set of Boolean (a.k.a bitmask) (native support in both C/C++ and Java)
An integer is stored in computer memory as a sequence of bits. This can be used to represent
lightweight small set of Boolean. All operations on this set of Boolean uses bit manipulation
of the corresponding integer, which makes it much faster than C++ STL vector<bool> or
bitset. Some important operations that we used in this book are shown below.

1. Representation: 32-bit (or 64-bit) integer, up to 32 (or 64) items. Without loss of
generality, all our examples below assume that we use a 32-bit integer called S.
Example: 5| 4| 3| 2| 1| 0 <- 0-based indexing from right
32|16| 8| 4| 2| 1 <- power of 2
S = 34 (base 10) = 1| 0| 0| 0| 1| 0 (base 2)
2. To multiply/divide an integer by 2, we just need to shift left/right the corresponding
bits of the integer, respectively. This operation (especially shift left) is important for
the next few operations below.
S = 34 (base 10) = 100010 (base 2)
S = S << 1 = S * 2 = 68 (base 10) = 1000100 (base 2)
S = S >> 2 = S / 4 = 17 (base 10) = 10001 (base 2)
S = S >> 1 = S / 2 = 8 (base 10) = 1000 (base 2) <- last ‘1’ is gone
3. To set/turn on the j-th item of the set, use S |= (1 << j).
S = 34 (base 10) = 100010 (base 2)
j = 3, 1 << j = 001000 <- bit ‘1’ is shifted to left 3 times
-------- OR (true if one of the bit is true)
S = 42 (base 10) = 101010 (base 2) // this new value 42 is updated to S
4. To check if the j-th item of the set is on (or off), use T = S & (1 << j). If T = 0,
then the j-th item of the set is off. If T != 0, then the j-th item of the set is on.
S = 42 (base 10) = 101010 (base 2)
j = 3, 1 << j = 001000 <- bit ‘1’ is shifted to left 3 times
-------- AND (only true if both bits are true)
T = 8 (base 10) = 001000 (base 2) -> not zero, so the 3rd item is on
S = 42 (base 10) = 101010 (base 2)
j = 2, 1 << j = 000100 <- bit ‘1’ is shifted to left 2 times
-------- AND
T = 0 (base 10) = 000000 (base 2) -> zero, so the 2rd item is off
3
Java Queue is only an interface that must be instantiated with Java LinkedList. See our sample codes.

23
2.2. DATA STRUCTURES WITH BUILT-IN LIBRARIES 
c Steven & Felix

5. To clear/turn off the j-th item of the set, use4 S &= ∼(1 << j).

S = 42 (base 10) = 101010 (base 2)


j = 1, ~(1 << j) = 111101 <- ‘~’ is the bitwise NOT operation
-------- AND
S = 40 (base 10) = 101000 (base 2) // this new value 40 is updated to S

6. To toggle the j-th item of the set, use S ∧= (1 << j).

S = 40 (base 10) = 101000 (base 2)


j = 2, (1 << j) = 000100 <- bit ‘1’ is shifted to left 4 times
-------- XOR (only true if both bits are different)
S = 44 (base 10) = 101100 (base 2) // this new value 44 is updated to S

7. To get the first bit that is on (from right), use T = (S & (-S)).

S = 40 (base 10) = 000...000101000 (32 bits, base 2)


-S = -40 (base 10) = 111...111011000 (32 bits, base 2, two’s complement)
----------------- AND
T = 8 (base 10) = 000...000001000 (the 3rd bit from right is on)

8. To turn on all bits in a set of size n, use S = (1 << n) - 1.

Example for n = 6
S + 1 = 64 (base 10) = 1000000 <- bit ‘1’ is shifted to left 6 times
1
--------- -
S = 63 (base 10) = 111111 (base 2)

Many bit manipulation operations are written as macros in our C/C++ example codes
(but written as usual in our Java example codes as Java does not support macro).

Example codes: ch2 04 bit manipulation.cpp; ch2 04 bit manipulation.java

Programming exercises to practice using linear data structures (and algorithms) with libraries:
• Basic Data Structures5
1. UVa 00394 - Mapmaker (1D array manipulation)
2. UVa 00414 - Machined Surfaces (1D array manipulation, get longest stretch of ‘B’s)
3. UVa 00466 - Mirror Mirror (2D array manipulation)
4. UVa 00467 - Synching Signals (linear scan on 1D array)
5. UVa 00482 - Permutation Arrays (1D array manipulation)
6. UVa 00541 - Error Correction (2d array manipulation)
7. UVa 00591 - Box of Bricks (1D array manipulation)
8. UVa 00594 - One Little, Two Little ... (manipulate bit string easily with bitset)
9. UVa 00700 - Date Bugs (can be solved with bitset)
10. UVa 10016 - Flip-flop the Squarelotron (tedious 2D array manipulation)
11. UVa 10038 - Jolly Jumpers (1D array manipulation)
12. UVa 10050 - Hartals (1D boolean array manipulation)
13. UVa 10260 - Soundex (Direct Addressing Table for soundex code mapping)
14. UVa 10703 - Free spots (just use small 2D array of size 500 × 500)
15. UVa 10855 - Rotated squares (2D string array manipulation, 90o clockwise rotation)
16. UVa 10920 - Spiral Tap (simulate the process)
4
Use brackets a lot when doing bit manipulation to avoid unnecessary bugs with operator precedence.
5
Various data structures under this subcategory are: Static array, C++ STL vector, bitset, lightweight set of
Boolean (bit manipulation of integers), Direct Addressing Table, list (Java Vector, ArrayList, LinkedList).

24
2.2. DATA STRUCTURES WITH BUILT-IN LIBRARIES 
c Steven & Felix

17. UVa 10978 - Let’s Play Magic (1D string array manipulation)
18. UVa 11040 - Add bricks in the wall (non trivial 2D array manipulation)
19. UVa 11192 - Group Reverse (1D character array manipulation)
20. UVa 11222 - Only I did it (use several 1D arrays to simplify this problem)
21. UVa 11340 - Newspaper * (Direct Addressing Table)
22. UVa 11349 - Symmetric Matrix (2D array manipulation)
23. UVa 11360 - Have Fun with Matrices (2D array manipulation)
24. UVa 11364 - Parking (1D array manipulation)
25. UVa 11496 - Musical Loop (1D array manipulation)
26. UVa 11581 - Grid Successors * (2D array manipulation)
27. UVa 11608 - No Problem (1D array manipulation)
28. UVa 11760 - Brother Arif, Please ... (row+col checks are separate; use two 1D arrays)
29. UVa 11835 - Formula 1 (2D array manipulation)
30. UVa 11933 - Splitting Numbers (an exercise for bit manipulation)
31. UVa 11988 - Broken Keyboard ... * (rare problem using linked list)
32. IOI 2011 - Pigeons (this problem is simpler if contestants know bit manipulation)
• C++ STL algorithm (Java Collections)
1. UVa 00123 - Searching Quickly (modified comparison function, use sort)
2. UVa 00146 - ID Codes * (use next permutation)
3. UVa 10194 - Football a.k.a. Soccer (multi-fields sorting, use sort)
4. UVa 10258 - Contest Scoreboard * (multi-fields sorting, use sort)
5. UVa 10880 - Colin and Ryan (use sort)
6. UVa 10905 - Children’s Game (modified comparison function, use sort)
7. UVa 11039 - Building Designing (use sort then count different signs)
8. UVa 11321 - Sort Sort and Sort (be careful with negative mod!)
9. UVa 11588 - Image Coding * (sort simplifies the problem)
10. UVa 11621 - Small Factors (generate numbers with factor 2 and/or 3, sort, upper bound)
11. UVa 11777 - Automate the Grades (sort simplifies the problem)
12. UVa 11824 - A Minimum Land Price (sort simplifies the problem)
13. LA 3173 - Wordfish (Manila06) (STL next permutation, prev permutation)
• Sorting-related problems
1. UVa 00110 - Meta-loopless sort (Ad Hoc)
2. UVa 00299 - Train Swapping (inversion index6 problem; O(n2 ) bubble sort)
3. UVa 00450 - Little Black Book (tedious sorting problem)
4. UVa 00612 - DNA Sorting (inversion index + stable sort)
5. UVa 00855 - Lunch in Grid City * (sort, median)
6. UVa 10107 - What is the Median? (sort, median; or nth element in <algorithm>)
7. UVa 10327 - Flip Sort (inversion index - solvable with O(n2 ) bubble sort)
8. UVa 10810 - Ultra Quicksort (inversion index - requires O(n log n) merge sort7 )
9. UVa 11462 - Age Sort * (counting sort problem8 , discussed in [3].)
10. UVa 11495 - Bubbles and Buckets (inversion index - requires O(n log n) merge sort)
11. UVa 11714 - Blind Sorting (decision tree to find min and 2nd min)
12. UVa 11858 - Frosh Week * (inversion index; O(n log n) merge sort; long long)
6
Count how many ‘bubble sort’ swaps (swap between pair of consecutive items) are needed to make the list sorted.
For example, if the array content is {4, 1, 2, 3}, we need 3 ‘bubble sort’ swaps to make this array sorted.
7
The O(n log n) solution for this inversion index problem is to modify merge sort. Let assume we sort ascending.
During the merge process, if the front of the right sorted subarray is taken first rather than the front of the left sorted
subarray, we say that ‘inversion occurs’. Add inversion index by the size of the current left subarray.
8
The idea of counting sort is simple, but it is only applicable to sort an array of integers with small range (like
‘human age’ of [1..99] years in UVa 11462). Do one pass through the array to count the frequency of each integer.
Suppose the array is {0, 1, 0, 0, 3, 1}. With one pass, we know that freq[0] = 3, freq[1] = 2, freq[2] =
0, freq[3] = 1. Then we simply display 0 three times, 1 two times, 2 zero time (no output), 3 one time, to get the
sorted array {0, 0, 0, 1, 1, 3}. Counting sort is used in our Suffix Array implementation in Section 6.6.4.

25
2.2. DATA STRUCTURES WITH BUILT-IN LIBRARIES 
c Steven & Felix

• C++ STL stack (Java Stack)


1. UVa 00120 - Stacks Of Flapjacks (Ad Hoc, pancake sorting)
2. UVa 00127 - “Accordian” Patience (shuffling stack)
3. UVa 00514 - Rails * (use stack to simulate the process)
4. UVa 00551 - Nesting a Bunch of Brackets (bracket matching with stack, classic)
5. UVa 00673 - Parentheses Balance (similar to UVa 551, classic)
6. UVa 00727 - Equation * (infix to postfix conversion, classic)
7. UVa 00732 - Anagram by Stack (use stack to simulate the process)
8. UVa 10858 - Unique Factorization (use stack to help solving this problem)
9. UVa 11111 - Generalized Matrioshkas * (bracket matching with some twists)
Also see: stack inside any recursive function calls (implicitly)
• C++ STL queue (Java Queue)
1. UVa 00540 - Team Queue (modified ‘queue’)
2. UVa 10172 - The Lonesome Cargo ... * (simulation with both queue and stack)
3. UVa 10901 - Ferry Loading III * (simulation with queue)
4. UVa 10935 - Throwing cards away I (simulation with queue)
5. UVa 11034 - Ferry Loading IV * (simulation with queue)
6. IOI 2011 - Hottest (practice task; ‘sliding window’; double ended queue/deque)
7. IOI 2011 - Ricehub (solvable with ‘sliding window’; double ended queue/deque)
Also see: queue inside BFS (see Section 4.2.2)

2.2.2 Non-Linear Data Structures


For some problems, there are better ways to organize the data other than storing the data linearly.
With efficient implementation of non-linear data structures shown below, you can operate on the
data in a faster manner, which can speed up the algorithms that use them.
For example, if you want to store a dynamic collection of pairs (e.g. name → index pairs), then
using C++ STL map below can give you O(log n) performance for insertion/search/deletion with
just few lines of codes whereas storing the same information inside one static array of struct may
require O(n) insertion/search/deletion and you have to code it by yourself.

• Balanced Binary Search Tree (BST): C++ STL map/set (Java TreeMap/TreeSet)
BST is one way to organize data as a tree structure. In each subtree rooted at x, this BST
property holds: Items on the left subtree of x are smaller than x and items on the right
subtree of x are greater than (or equal to) x. This is a spirit of Divide and Conquer (also
see Section 3.3). Organizing the data like this (see Figure 2.1, left) allows O(log n) insertion,
search, and deletion as only O(log n) worst case root-to-leaf scan is needed to perform these
operations (see [3, 2] for details) – but this only works if the BST is balanced.

Figure 2.1: Examples of BST (Left) and (Max) Heap (Right)

Implementing a bug-free balanced BST like the Adelson-Velskii Landis (AVL)9 or Red-Black
9
AVL tree is the first self-balancing BST to be invented. AVL tree has one more property on top of BST property:
The heights of the two subtrees of any vertex can only differ by at most one. Rebalancing act is performed (when
necessary) during insertions and deletions to maintain this property.

26
2.2. DATA STRUCTURES WITH BUILT-IN LIBRARIES 
c Steven & Felix

(RB)10 Tree is tedious and hard to do under time constrained contest environment (unless
you have prepared a library code beforehand). Fortunately, C++ STL has map and set (Java
TreeMap and TreeSet) which are usually the implementation of RB Tree which guarantee all
insertion/search/deletion operations are done in O(log n). By mastering these two STLs, you
can save a lot of precious coding time during contests11 ! The difference between these two
data structures is simple: C++ STL map stores (key → data) pair whereas C++ STL set
only stores the key.

Example codes: ch2 05 stl map set.cpp; ch2 05 TreeMap TreeSet.java

• Heap: C++ STL priority queue (Java PriorityQueue)


Heap is another way to organize data as a tree structure. Heap is also a binary tree like
BST but it must be complete 12 . Instead of enforcing the BST property, (Max) Heap enforces
the Heap property: In each subtree rooted at x, items on the left and the right subtrees
of x are smaller than (or equal to) x (see Figure 2.1, right). This is also a spirit of Divide
and Conquer (also see Section 3.3). This property guarantees that the top of the heap is
the maximum element. There is usually no notion of ‘search’ in Heap, but only deletion of
the maximum element and insertion of new item – which can be easily done by traversing a
O(log n) root-to-leaf or leaf-to-root path (see [3, 2] for details).
(Max) Heap is useful to model a Priority Queue, where item with the highest priority (the
maximum element) can be dequeued from the priority queue in O(log n) and new item can be
enqueue into the priority queue also in O(log n). The implementation of priority queue is
available in C++ STL queue (Java PriorityQueue). Priority Queue is an important compo-
nent in algorithms like Prim’s (and Kruskal’s) algorithm for Minimum Spanning Tree (MST)
problem (Section 4.3) and Dijkstra’s algorithm for Single-Source Shortest Paths (SSSP) prob-
lem (Section 4.4.3).
This data structure is also used to perform partial sort in C++ STL algorithm. This is
done by dequeuing the maximum element k times where k is the number of the top most
items to be sorted. As each dequeue operation is O(log n), partial sort has O(k log n) time
complexity13 . When k = n, this algorithm is called heap sort. Note that although the time
complexity of heap sort is O(n log n), heap sort is usually slower than quick sort because heap
operations have to access data that are stored in very different indices, thus decreasing the
performance of cache memory.

Example codes: ch2 06 stl priority queue.cpp; ch2 06 PriorityQueue.java

• Hash Table: no native C++ STL support (Java HashMap/HashSet/HashTable)


Hash Table is another non-linear data structures, but we do not recommend using it in
programming contests unless necessary. Reasons: Designing a good performing hash function
is quite tricky and there is no native C++ STL support for it14 . Moreover C++ STL map
or set (Java TreeMap or TreeSet) are usually good enough as the typical input size of
programming contest problems are usually not more than 1M , making the performance of
O(1) for Hash Table and O(log 1M ) for balanced BST do not differ by much.
10
Red-Black tree is another self-balancing BST. Every vertex has color attribute: either red or black. The root is
black. All leaves are black. Both children of every red vertex are black. Every simple path from a vertex to any of
its descendant leaves contains the same number of black vertices. Throughout insertions and deletions, RB tree will
maintain all these properties to keep the tree balanced.
11
However, for some tricky contest problems where you have to ‘augment your data structure’ (see Chapter 14 of
[3]), AVL Tree knowledge is needed as C++ STL map or set cannot be augmented easily.
12
Complete binary tree is a binary tree in which every level, except possibly the last, is completely filled, and all
vertices are as far left as possible. Complete binary tree can be stored in a compact array.
13
You may have noticed that the time complexity of partial sort is O(k log n) where k is the output size and n
is the typical input size. This is called ‘output-sensitive’ algorithm since its runtime does not only depends on the
input size but also depends on the amount of items that it has to output.
14
Java has Hash related classes, but we decide not to use them yet in this book.

27
2.2. DATA STRUCTURES WITH BUILT-IN LIBRARIES 
c Steven & Felix

However, a form of Hash Table is actually used in contests, namely ‘Direct Addressing Table’
(DAT), where the key itself is the index, bypassing the need of a ‘hash function’. For example,
we may need to assign all possible ASCII characters [0-255] to integer values, e.g. ‘a’ → ’3’,
‘W’ → ’10’, . . . , ‘I’ → ‘13’. In this case, we do not need to use C++ STL map or any form
of hashing as the key itself (the ASCII character) is unique and sufficient to determine the
appropriate index in the array of size 256.

Exercise 2.2.2.1: Which non linear data structure that you will use if you have to support the
following three dynamic operations: 1) many insertions, 2) many deletions, and 3) many requests
to print data currently in the structure in sorted order.
Exercise 2.2.2.2: There are M strings. N of them are unique (obviously N ≤ M). Which non
linear data structure that you will use if you have to index these M strings with integers from
[0..N-1]? The indexing criteria is up to you, but similar strings must be given similar index!

Programming exercises to practice using non-linear data structures with libraries:

• C++ STL priority queue (Java PriorityQueue)15


1. UVa 10954 - Add All * (use priority queue, greedy)
2. UVa 11995 - I Can Guess ... * (simulation using stack, queue, priority queue)
3. LA 3135 - Argus (Beijing04) (use priority queue)
Also see: priority queue inside topological sort variant (see Section 4.2.1)
Also see: priority queue inside Kruskal’s algorithm16 (see Section 4.3.2)
Also see: priority queue inside Prim’s algorithm (see Section 4.3.3)
Also see: priority queue inside Dijkstra’s algorithm (see Section 4.4.3)
• C++ STL map/set (Java TreeMap/TreeSet)
1. UVa 00417 - Word Index (generate all words, add to map for auto sorting)
2. UVa 00484 - The Department of ... (map: maintain freq, vector: input order)
3. UVa 00501 - Black Box (use multiset with efficient iterator manipulation)
4. UVa 00642 - Word Amalgamation (use map)
5. UVa 00755 - 487-3279 (use map to simplify this problem)
6. UVa 00860 - Entropy Text Analyzer (use map for frequency counting)
7. UVa 10226 - Hardwood Species * (use map; use hashing for better performance)
8. UVa 10282 - Babelfish (use map)
9. UVa 10295 - Hay Points (use map)
10. UVa 10374 - Election (use map)
11. UVa 10686 - SQF Problem (use map)
12. UVa 10815 - Andy’s First Dictionary (use set and string)
13. UVa 11062 - Andy’s Second Dictionary (similar to UVa 10815, but with more twist)
14. UVa 11136 - Hoax or what (use map)
15. UVa 11239 - Open Source (use map and set to check previous strings efficiently)
16. UVa 11286 - Conformity * (use map to keep track the frequency of a combination)
17. UVa 11308 - Bankrupt Baker (use map and set to help manage the data)
18. UVa 11629 - Ballot evaluation * (use map)
19. UVa 11849 - CD (use set to pass the time limit, better: use hashing!)
20. UVa 11860 - Document Analyzer (use set and map, linear scan)

15
The default setting of C++ STL priority queue is a Max Heap (larger to smaller) whereas the default setting of
Java PriorityQueue is a Min Heap (smaller to larger). Tips: A Max Heap containing numbers can be easily reversed
into a Min Heap (and vice versa) by inserting the negative version of those numbers. This is because the sort order
of a set of positive numbers is the reverse of its negative version. This trick is used several time in this book.
16
This is another way to implement Kruskal’s algorithm. The implementation shown in Section 4.3.2 uses vector
+ sort instead of priority queue.

28
2.3. DATA STRUCTURES WITH OUR-OWN LIBRARIES 
c Steven & Felix

2.3 Data Structures with Our-Own Libraries


As of 1 August 2011, important data structures shown in this section do not have built-in support
yet in C++ STL or Java API. Thus, to be competitive, contestants must have bug-free implemen-
tations of these data structures ready. In this section, we discuss the ideas and the implementation
examples of these data structures.

2.3.1 Graph
Graph is a pervasive data structure which appears in many Computer Science problems. Graph
in its basic form is simply a collection of vertices and edges (that store connectivity information
between those vertices). Later in Chapter 3, 4, and 8, we will explore many important graph
problems and algorithms. To get ourselves ready, we discuss three basic ways (there are a few
others) to store the information of a graph G with V vertices and E edges in this subsection.

Figure 2.2: Example of various Graph representations

A Adjacency Matrix, usually in the form of 2D array (see Figure 2.2.A).


In contest problems involving graph, usually the number of vertices V is known, thus we can
build a ‘connectivity table’ by setting up a 2D static array: int AdjMat[V ][V ]. This has
space 17 complexity of O(V 2 ). For an unweighted graph, we set AdjMat[i][j] = 1 if there is
an edge between vertex i-j and set 0 otherwise. For a weighted graph, we set AdjMat[i][j] =
weight(i, j) if there is an edge between vertex i-j with weight(i, j) and set 0 otherwise.
Adjacency Matrix is good if the connectivity between two vertices in a small dense graph is
frequently queried. But it is not good for large sparse graph as it takes too much space (O(V 2 ))
and there are too many cells in the 2D array that are blank (contain zeroes). In programming
contest setting, it is usually infeasible to use Adjacency Matrix when the given V is larger than
1000. Another drawback of Adjacency Matrix is that it also requires O(V ) time to enumerate
the list of neighbors of a vertex v – an operation commonly used in many graph algorithms –
even if vertex v only has a handful of neighbors. A more compact and efficient form of graph
representation is the Adjacency List discussed below.

B Adjacency List, usually in the form of vector of vector pairs (see Figure 2.2.B).
Using C++ STL: vector<vii> AdjList, with vii defined as:
typedef pair<int, int> ii; typedef vector<ii> vii; // our data type shortcuts
Using Java API: Vector< Vector < IntegerPair > > AdjList.
IntegerPair is a simple class that contains pair of integers like ii above.
In Adjacency List, we have a vector of vector pairs. For each vertex v, we store the list of
neighbors of v as ‘edge information’ pairs. Each ‘edge information’ pair contains two information,
the vertex number of the neighboring vertex and the edge weight. If the graph is unweighted,
17
In this subsection, we differentiate space complexity with time complexity. Space complexity is an asymptotic
measure of space taken by a data structure. Time complexity is an asymptotic measure of time taken to run a certain
algorithm (in this case, the operation on the data structure).

29
2.3. DATA STRUCTURES WITH OUR-OWN LIBRARIES 
c Steven & Felix

simply store weight = 0 (or 1) or drop this second attribute18 . The space complexity of this
graph representation is only O(V + E) because if there are E bidirectional edges in the graph,
this Adjacency List only stores 2E ‘edge information’ pairs. As E is usually much smaller than
V × (V − 1)/2 = O(V 2 ) – the maximum number of edges in a complete graph, Adjacency List
is more space efficient than Adjacency Matrix.
With Adjacency List, we can enumerate the list of neighbors of a vertex v efficiently. If v has
k neighbors, this enumeration is O(k). As this is one of the most common operations in most
graph algorithms, it is advisable to set Adjacency List as your first choice. Unless otherwise
stated, almost all graph algorithms discussed in this book use Adjacency List.
C Edge List, usually in the form of vector of triples (see Figure 2.2.C).
Using C++ STL: vector< pair<int, ii> > EdgeList.
Using Java API: Vector< IntegerTriple > EdgeList.
IntegerTriple is a simple class that contains triple of integers like pair<int, ii> above.
In Edge List, we store a list of all E edges, usually in some sorted order. The space complexity
of this data structure is clearly O(E). This graph representation is very useful for Kruskal’s
algorithm for MST (Section 4.3.2) where the collection of edges are sorted19 by their length
from shortest to longest. However, storing graph information in Edge List complicates many
graph algorithms that work by enumerating edges that are incident to a vertex.

Example codes: ch2 07 graph ds.cpp; ch2 07 graph ds.java

Exercise 2.3.1.1: Show the Adjacency Matrix, Adjacency List, and Edge List of the graphs shown
in Figure 4.1 (Section 4.2.1) and in Figure 4.8 (Section 4.2.9).
Exercise 2.3.1.2: Given a graph in one representation (Adjacency Matrix/AM, Adjacency List/AL,
or Edge List/EL), show how to convert it to another representation! There are 6 possible combi-
nations here: AM to AL, AM to EL, AL to AM, AL to EL, EL to AM, and EL to AL.
Exercise 2.3.1.3: Given a graph represented by an Adjacency Matrix, transpose it (reverse the
direction of each edges). How to do the same with Adjacency List?

Implicit Graph
Some graphs do not need to be stored in a graph data structure yet we can have the com-
plete graph information. Such graph is called implicit graph. You will encounter them in the
subsequent chapters. There are two forms of implicit graphs:

1. The edges can be determined easily


For example: A 2D grid. The vertices are the cells in the 2D grid. The edges can be
determined easily: Two neighboring cells in the grid have an edge between them.
2. The edges can be determined with some rules
For example: A graph contains N vertices numbered from [0..N-1]. There is an edge
between two vertices i and j if (i + j) is a prime.

2.3.2 Union-Find Disjoint Sets


Union-Find Disjoint Sets is a data structure to model a collection of disjoint sets which has the
ability to efficiently20 1) ‘find’ which set an item belongs to (or to test whether two items belong
to the same set) and 2) ‘union’ two disjoint sets into one bigger set.
18
For simplicity, in all graph implementations in this book, we will always assume that the second attribute exists
although it is not always used.
19
pair objects in C++ can be easily sorted. The default sorting criteria is to sort based on the first item, and if tie,
based on the second item. In Java, we can write an IntegerPair/IntegerTriple class that implements Comparable.
20
M operations of this data structure runs in O(M × α(n)). However, the inverse Ackermann function α(n) grows
very slowly, i.e. its value is just less than 5 for any practical input size n. So, we can treat α(n) as constant.

30
2.3. DATA STRUCTURES WITH OUR-OWN LIBRARIES 
c Steven & Felix

These two operations are useful for Kruskal’s algorithm (Section 4.3.2) or problems that involve
‘partitioning’, like keeping track of connected components of an undirected graph (Section 4.2.3).
These seemingly simple operations are
not efficiently supported by the C++
STL set (Java TreeSet) which only deals
with a single set. Having a vector of
sets and looping through each one to find
which set an item belongs to is expensive!
C++ STL set union (in <algorithm>)
is also not efficient enough although it
combines two sets in linear time, as we
still have to deal with the shuffling of the
content inside the vector of sets! We
need a better data structure: The Union-
Find Disjoint Sets – discussed below.
The key idea of this data structure is
to keep a representative (‘parent’) item of
each set. This information is stored in vi
pset, where pset[i] tells the representa-
tive item of the set that contains item i.
See Figure 2.3, initSet(5). This func-
tion creates 5 items: {0, 1, 2, 3, 4} as 5
disjoint sets of 1 item each. Each item
initially has itself as the representative.
When we want to merge two sets, we
call unionSet(i, j) which makes both
items ‘i’ and ‘j’ to have the same represen-
tative item – directly or indirectly21 (see
Path Compression below). This is done
by calling findSet(j) – to find out the
representative of item ‘j’, and assign that
value to pset[findSet(i)] – to update
the parent of the representative item of
item ‘i’. This is efficient.
See Figure 2.3, unionSet(0, 1),
unionSet(1, 2), and unionSet(3, 1).
These three sub figures show what is hap-
pening when we call unionSet(i, j):
Each union is simply done by changing
the representative item of one item to
point to the other’s representative item.
See Figure 2.3, findSet(0). This
function findSet(i) recursively calls it-
self whenever pset[i] is not yet itself
(‘i’). Then, once it finds the main rep- Figure 2.3: Union-Find Disjoint Sets
resentative item (e.g. ‘x’) for that set, it
will compress the path by saying pset[i] = x. Thus subsequent calls of findSet(i) will be O(1).
This simple strategy is aptly named as ‘Path Compression’.
Figure 2.3, isSameSet(0, 4) shows another operation for this data structure. This function
isSameSet(i, j) simply calls findSet(i) and findSet(j) to check if both refer to the same
representative item. If yes, ‘i’ and ‘j’ belong to the same set, otherwise, they do not.
21
See Figure 2.3. After we call unionSet(1, 2), notice that parent of 1 is now 2, but parent of 0 is still 1. This
will not be updated until we call findSet(0) later which will use the ‘Path Compression’ strategy.

31
2.3. DATA STRUCTURES WITH OUR-OWN LIBRARIES 
c Steven & Felix

Our library implementation for Union-Find Disjoint Sets is just these few lines of codes:
vi pset; // remember: vi is vector<int>
void initSet(int N) { pset.assign(N, 0);
for (int i = 0; i < N; i++) pset[i] = i; }
int findSet(int i) { return (pset[i] == i) ? i : (pset[i] = findSet(pset[i])); }
bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
void unionSet(int i, int j) { pset[findSet(i)] = findSet(j); }
Example codes: ch2 08 unionfind ds.cpp; ch2 08 unionfind ds.java
Exercise 2.3.2.1: There are two more queries that are commonly performed on the Union-Find
Disjoint Sets data structure: int numDisjointSets() that returns the number of disjoint sets
currently in the structure and int sizeOfSet(int i) that returns the size of set that currently
contains item i. Update the codes shown in this section to support these two queries efficiently!
Exercise 2.3.2.2: There is another strategy to speed up the implementation of Union-Find Disjoint
Sets data structure: The ‘union by rank’ strategy. The idea is to give rank (upper bound of the
height of the tree) to each disjoint sets. Then during unionSet(i, j) operation, we set the parent
of the set with fewer members to point to the parent of the set with more members, thereby
keeping the resulting tree ‘more balanced’ and thus ‘shorter’. For example, in Figure 2.3, when we
do unionSet(3, 1), it is beneficial to set parent of vertex 3 (which is 3 itself) to point to parent
of vertex 1 (which is 2) rather than setting parent of vertex 1 (which is 2) to point to parent of
vertex 3 (which is 3 itself). The first approach yields a new tree of height 3 as shown in Figure 2.3,
whereas the second approach yields a new tree of height 4. Do you think this heuristic will help
speed up the data structure significantly? If yes, in which case(s)? Is there any programming trick
to achieve similar effect without using this heuristic?

2.3.3 Segment Tree


In this subsection, we discuss a data structure which can efficiently answer dynamic 22 range queries.
One such range query is the problem of finding the index of the minimum element in an array within
range [i..j]. This is more commonly known as the Range Minimum Query (RMQ). For example,
given an array A of size n = 7 below, RMQ(1, 3) = 2, as the index 2 contains the minimum element
among A[1], A[2], and A[3]. To check your understanding of RMQ, verify that on the array A
below, RMQ(3, 4) = 4, RMQ(0, 0) = 0, RMQ(0, 1) = 1, and RMQ(0, 6) = 5.
Array | Values = 8 | 7 | 3 | 9 | 5 | 1 | 10
A | Indices = 0 | 1 | 2 | 3 | 4 | 5 | 6
There are several ways to answer this RMQ. One trivial algorithm is to simply iterate the array
from index i to j and report the index with the minimum value. But this is O(n) per query. When
n is large, such an algorithm maybe infeasible.
In this section, we answer the RMQ with Segment Tree which is another way to arrange data
as a binary tree. For the array A above, its corresponding segment tree is shown in Figure 2.4.
The root of this tree contains the full segment [0, n-1]. And for each segment [L, R], we split
them into [L, (L+R)/2] and [(L+R)/2 + 1, R] until L = R. See the O(n log n) built st routine
below. With the segment tree ready, answering an RMQ can now be done in O(log n).
The answer for RMQ(i, i) is trivial, which is i itself. But for general cases, RMQ(i, j), further
check is needed. Let p1 = RMQ(i, (i + j) / 2) and p2 = RMQ((i + j) / 2 + 1, j). Then
RMQ(i, j) is p1 if A[p1] ≤ A[p2], p2 otherwise.
For example, we want to answer RMQ(1, 3). The execution in Figure 2.4 (solid lines) is as
follows: Start from the root which represents segment [0, 6]. We know that the answer for
RMQ(1, 3) cannot be the stored minimum value of segment [0, 6] = 5 as it is the minimum
value over a larger23 segment [0, 6] than the RMQ(1, 3). From the root, we have to go to the left
22
In dynamic data structure, we frequently update and query the data, which usually make pre-processing useless.
23
Segment [L, R] is said to be larger than query range [i, j] if L ≤ i && j ≤ R.

32
2.3. DATA STRUCTURES WITH OUR-OWN LIBRARIES 
c Steven & Felix

subtree as the root of the right subtree is segment [4, 6] which is outside24 the RMQ(1, 3).
We now move to the left subtree that represents segment [0, 3]. This segment [0, 3] is still
larger than the RMQ(1, 3). In fact RMQ(1, 3) intersects both the left segment [0, 1] and the
right segment [2, 3] of segment [0, 3], so we have to continue exploring both subtrees.
The left segment [0, 1] of [0, 3] is not yet inside the RMQ(1, 3), so another split is necessary.
From segment [0, 1], we move right to segment [1, 1], which is now inside25 the RMQ(1, 3). At
this point, we know that RMQ(1, 1) = 1 and we return this value to the caller. The right segment
[2, 3] of [0, 3] is inside the required RMQ(1, 3). From the stored minimum value inside this
vertex, we know that RMQ(2, 3) = 2. We do not need to traverse further down.
Now, back in segment [0, 3], we now have p1 = RMQ(1, 1) = 1 and p2 = RMQ(2, 3) = 2.
Because A[p1] > A[p2] since A[1] = 7 and A[2] = 3, we now have RMQ(1, 3) = p2 = 2.

Figure 2.4: Segment Tree of Array A = {8, 7, 3, 9, 5, 1, 10}

Now let’s take a look at another example: RMQ(4, 6). The execution in Figure 2.4 (dashed line)
is as follows: We again start from the root segment [0, 6]. Since it is larger than the RMQ(4, 6),
we move right to segment [4, 6]. Since this segment is exactly the RMQ(4, 6), we simply return
the index of minimum element that is stored in this vertex, which is 5. Thus RMQ(4, 6) = 5. We
do not have to traverse the unnecessary parts of the tree!
In the worst case, we have two root-to-leaf paths which is just O(2 × log n) = O(log n). For
example in RMQ(3, 4) = 4, we have one root-to-leaf path from [0, 6] to [3, 3] and another
root-to-leaf path from [0, 6] to [4, 4].
If the array A is static, then using Segment Tree to solve RMQ is overkill as there exists a
Dynamic Programming (DP) solution that requires O(n log n) one-time pre-processing and O(1)
per RMQ. This DP solution will be discussed later in Section 3.5.2.
Segment Tree is useful if the underlying data is frequently updated (dynamic). For example, if
A[5] is now changed from 1 to 100, then we just need to update the vertices along leaf to root path
in O(log n). See path: [5, 5] → [4, 5] → [4, 6] → [0, 6] in Figure 2.5. As a comparison, DP
solution requires another O(n log n) pre-processing to do the same. If we have to do such updates
many times, using Segment Tree is a better choice.

Figure 2.5: Updating Array A to {8, 7, 3, 9, 5, 100, 10}

Our Segment Tree implementation is shown below. The code shown here supports static RMQ
(the dynamic update part is left as exercise).
24
Segment [L, R] is said to be outside query range [i, j] if i > R || j < L.
25
Segment [L, R] is said to be inside query range [i, j] if L ≥ i && R ≤ j.

33
2.3. DATA STRUCTURES WITH OUR-OWN LIBRARIES 
c Steven & Felix

Note that there are of course other ways to implement Segment Tree, e.g. a more efficient
version that only expands the segments only when needed.

#include <cmath>
#include <cstdio>
#include <vector>
using namespace std;
typedef vector<int> vi;

// Segment Tree Library: The segment tree is stored like a heap array
void st_build(vi &t, const vi &A, int vertex, int L, int R) {
if (L == R) // as L == R, either one is fine
t[vertex] = L; // store the index
else { // recursively compute the values in the left and right subtrees
int nL = 2 * vertex, nR = 2 * vertex + 1;
st_build(t, A, nL, L , (L + R) / 2); // this is O(n log n)
st_build(t, A, nR, (L + R) / 2 + 1, R ); // similar analysis as
int lContent = t[nL] , rContent = t[nR]; // with merge sort
int lValue = A[lContent], rValue = A[rContent];
t[vertex] = (lValue <= rValue) ? lContent : rContent;
} }

void st_create(vi &t, const vi &A) { // if original array size is N,


// the required segment tree array length is 2*2^(floor(log2(N)) + 1);
int len = (int)(2 * pow(2.0, floor((log((double)A.size()) / log(2.0)) + 1)));
t.assign(len, 0); // create vector with length ‘len’ and fill it with zeroes
st_build(t, A, 1, 0, (int)A.size() - 1); // recursively build the segment tree
}

int st_rmq(vi &t, const vi &A, int vertex, int L, int R, int i, int j) {
if (i > R || j < L) return -1; // current segment outside query range
if (L >= i && R <= j) return t[vertex]; // current segment inside query range

// compute the minimum position in the left and right part of the interval
int p1 = st_rmq(t, A, 2 * vertex , L , (L + R) / 2, i, j);
int p2 = st_rmq(t, A, 2 * vertex + 1, (L + R) / 2 + 1, R , i, j);

// return the position where the overall minimum is


if (p1 == -1) return p2; // if we try to access segment outside query
if (p2 == -1) return p1; // same as above
return (A[p1] <= A[p2]) ? p1 : p2; }

int st_rmq(vi &t, const vi& A, int i, int j) { // overloading, simpler arguments
return st_rmq(t, A, 1, 0, (int)A.size() - 1, i, j); }

int main() {
int arr[7] = { 8, 7, 3, 9, 5, 1, 10 }; // the original array
vi A(arr, arr + 7);
vi st; st_create(st, A);
printf("RMQ(1, 3) = %d\n", st_rmq(st, A, 1, 3)); // answer is index 2
printf("RMQ(4, 6) = %d\n", st_rmq(st, A, 4, 6)); // answer is index 5
} // return 0;

Example codes: ch2 09 segmenttree ds.cpp; ch2 09 segmenttree ds.java

34
Another Random Document on
Scribd Without Any Related Topics
VIII.
The Hill Mizar.
"All scenes alike engaging prove
To souls impress'd with sacred love!
Where'er they dwell, they dwell in Thee;
In heaven, in earth, or on the sea.

"To me remains nor place nor time;


My country is in every clime;
I can be calm and free from care
On any shore, since God is there.

"While place we seek, or place we shun,


The soul finds happiness in none;
But, with a God to guide our way,
'Tis equal joy to go or stay.

"Could I be cast where thou art not,


That were indeed a dreadful lot;
But regions none remote I call,
Secure of finding God in all."

—Cowper.

"It is profitable for Christians to be often calling to mind the


dealings of God with their souls. It was Paul's accustomed
manner, and that when tried for his life, even to open before his
judges the manner of his conversion. He would think of that day
and that hour in the which he did first meet with grace, for he
found it support onto him. There was nothing to David like
Goliath's sword. The very sight and remembrance of that did
preach forth God's deliverance to him. Oh, the remembrance of
my great sins, of my great temptations, and of my great fears
for perishing for ever. They bring afresh into my mind the
remembrance of mercy and help—my great support from
heaven, and the great grace that God extendeth to such a
wretch as I."—John Bunyan.
"O my God, my soul is cast down within me: therefore will I
remember thee from the land of Jordan, and of the Hermonites,
from the hill Mizar."—Verse 6.
VIII.
THE HILL MIZAR.
In the preceding verse, we found the Psalmist chiding his soul for
the unreasonableness of its depression—calling upon it to exercise
hope and trust in God, under the assurance that he would "yet
praise Him for the help of His countenance."
But "what will ye see in the Shulamite?" Another experience testifies
afresh, "As it were the company of two armies."[53] Hope has no
sooner risen to the surface than despondency returns. The
struggling believer threatens to sink. The wave is again beat back.
His soul is again "cast down!" But one word—an old monosyllable of
comfort—is borne on the refluent billow, "O my God!" This "strong
swimmer in his agony" seizes hold of that never-failing support, the
faithfulness of a covenant-keeping Jehovah. With this he breasts the
opposing tide, and will assuredly at last reach the shore. The very
tribulations that are casting him down,—threatening to submerge
him,—are only nerving his spirit for bolder feats; leading him to
value more the everlasting arms that are lower and deeper than the
darkest wave.
We have heard of a bell, set in a lighthouse, rung by the sweep of
the winds and the dash of the billows. In the calm, stormless sea, it
hung mute and motionless; but when the tempest was let loose and
the ocean fretted, the benighted seaman was warned by its chimes;
and beating hearts ashore, in the fisherman's lonely hut, listened to
its ominous music. We read in the previous verse, of the lighthouse
of Faith, built on the rock of Hope. God has placed bells there. But it
needs the storms of adversity to blow ere they are heard. In the
calm of uninterrupted prosperity, they are silent and still. But the
hurricane arises. The sea of life is swept with tempest, and, amid
the thick darkness, they ring the peal of heavenly confidence, "My
God, my God!"
My God! What a heritage of comfort do these words contain—in all
time of our tribulation—in all time of our wealth—in the hour of
death, and at the day of judgment! They describe the great Being
who fills heaven with His glory, as the covenant portion and heritage
of believers. His attributes are embarked on their side; His holiness
and righteousness, and justice and truth, are the immutable
guarantees and guardians of their everlasting well-being. Hear His
own gracious promise—"I will bring the third part through the fire,
and will refine them as silver is refined, and will try them as gold is
tried: they shall call on my name, and I will hear them: I will say, It
is my people: and they shall say, The Lord is my God."[54] Moreover,
He is the only possession which is theirs absolutely. All else they
have, is in the shape of a loan, which they receive as stewards. Their
time, their talents, their possessions, their friends, are only leased by
them from the Great Proprietor of life and being. But they can say
unreservedly, "The Lord is my portion." "God, even our OWN God,
shall bless us." Ay, and we are told, "God is not ashamed to be
called their God."[55] "The name of the Lord" is thus "a strong tower:
the righteous runneth into it, and is safe."[56] That salvation
purchased by Jesus,—the amazing method by which every attribute
of the Divine nature has been magnified, and every requirement of
the Divine law has been met,—is "for walls and bulwarks." The
believer not only can lay hold on higher blessings—"the good hope
through grace," "glory, honour, immortality, eternal life,"—but even
with regard to the circumstantials of the present, the appointments
and allotments in the house of his pilgrimage, he can feel that they
are so regulated and overruled as best to promote his spiritual
interests; and that "all things" (yes, "ALL things") are "working
together for his good." Take then, desponding one! the opening
words of David's lamentation. They quiet all apprehensions. This all-
gracious Being who gave His own Son for thee, must have some
wise reason in such discipline. Oh, confide all thy perplexities, and
this perplexity, into His hands, saying, "I am oppressed, undertake
Thou for me!" Who can forget that it was this same monosyllable of
comfort that cheered a greater Sufferer at a more awful hour? The
two most memorable spots in His midnight of agony,—Gethsemane
and Calvary, the Garden and the Cross,—have this solitary gleam of
sunshine breaking through the darkness, "O my Father!" "My God, my
God!"
Let us now proceed to the main feature in this verse. We have
already noted how the exiled King had tried to reason his soul out of
its depression by the exercise of Hope—by looking beyond the
shadows of the present to a brighter future. But the torch flickered
and languished in his hand. He adopts a new expedient. Instead of
looking to the future, he resolves to take a retrospective survey; he
directs his eye to the past. As often at eventide, when the lower
valleys are in shadow, the mountain-tops are gilded with the
radiance of the setting sun; so from the Valley of Humiliation, where
he now was, he looks back on the lofty memorials of God's
faithfulness. He "lifts his eyes unto the HILLS, from whence cometh
his help." "O my God, I will remember Thee!" "This is my infirmity,"
he seems to say, when he thinks of the weakness of his faith, and
the fitfulness of his frames and feelings: "but I will remember the
years of the right hand of the Most High. I will remember the works
of the Lord; surely I will remember Thy wonders of old."[57] With this
key he proceeds again to open the door of Hope. And as he treads
the valley of Achor, he "sings there as in the days of his youth."[58]
In connexion with this remembrance of his God, David alludes to
some well-known places in his Kingdom—"The land of Jordan, and
the Hermonites, and the hill Mizar."
What means he by this reference? His language may admit of a
twofold interpretation.
1. He may possibly refer to his present sojourn in the region beyond
Jordan, with the Hermon range in sight; and which had this
peculiarity, that it was beyond the old boundary-line of the Land of
Promise, making him for the time, "an alien from the commonwealth
of Israel."
We know from a passage in Joshua (chap. xxii.) how sacredly the
division between the covenant people and the neighbouring tribes
was preserved. The latter were denominated a "possession
unclean;" the former, "the land of the possession of the Lord,
wherein the Lord's tabernacle is." How bitter must it have been to a
patriotic heart like that of the Psalmist, thus to be cut off (even
though for a brief season) from all participation in national and
sanctuary blessings,—to stand outside the land trodden by the
footsteps of angels, consecrated by the ashes of patriarchs, and over
which hovered the shadowing wings of Jehovah!
But he exults in the persuasion that Israel's God is not confined to
lands or to sanctuaries. "I will remember Thee," says the banished
monarch. "Though wandering here beyond the region Thou hast
blest with Thy favour, I will not cease still to call Thee and claim
Thee as my God, and to recount all the manifold tokens of Thy
mercy, even though it be from the 'land of Jordan, and of the
Hermonites, from the hill Mizar.' My foes may drive me from my
home,—they may strip me of my regal glories,—they may make me
the butt of scorn, the mark for their arrows;—but they cannot banish
me from the better portion and heritage I have in Thy blessed self!"
If we should ever be in circumstances when, like David, we are
denuded of the means of grace—shut out from the public
ministrations of the sanctuary,—or, what is more common, placed in
a disadvantageous position for spiritual advancement;—when our
situation as regards the world, the family, business, pursuits,
companions, society, is such as to prove detrimental to the interests
of our souls,—let us still "remember God!" Let the loss of means,
and privileges, and opportunities, and congenial intercourse, draw us
nearer the Source of all knowledge, and peace, and true joy. If the
starlight be wanting, let us prize the sunlight more. If the streams
fail, let us go direct to the fountainhead.
Yes, and God can make His people independent of all outward
circumstances. In the court of an Ethiopian Queen there was a
believing Treasurer. In the household of Nero there were illustrious
saints. Down in the depths of the briny ocean, imprisoned in the
strangest of tombs, a disobedient prophet "remembered God," and
his prayer was heard. Joseph was torn away from the land of his
birth, and the home where his piety had been nurtured, but in Egypt
"the Lord was with Joseph." "At my first answer," says the apostle of
the Gentiles, "no man stood with me, but all men forsook me....
Notwithstanding, the Lord stood by me, and strengthened me."
Comforting thought! that the true Sanctuary, of which all earthly
ones are the shadowy type, is ever near: God himself, the refuge
and dwelling-place of His people to all generations, and who,
wherever we are, can turn the place of forlorn exile—our "land of
Jordan, the Hermonites, the hill Mizar"—into scenes bright with
manifestations of His covenant love.

2. But the references to these several localities may admit of a


different interpretation. David may be reverting to some memorable
epochs in his past history—some green spots in the waste of
memory, where he enjoyed peculiar tokens of God's grace and
presence.
We spoke in last chapter of Hope's picture-gallery. Memory has one,
stranger still—filled with landscapes of imperishable interest! Who
has not such a gallery in his own soul? Let Memory withdraw her
folding-doors—and what do we see? The old homes of cherished
infancy may be the first to crowd the walls and arrest the eye;—
scenes of life's bright morning, the sun tipping with his rising beam
the dim mountain-heights of the future! In the foreground, there is
the murmuring brook by which we wandered, and the umbrageous
tree under which we sat;—countenances glowing with smiles are
haunting every walk and greeting us at every turn—the ringing laugh
of childhood at some—venerable forms bending at others.
But more hallowed remembrances crowd the canvas. Ebenezers and
Bethel-stones appear conspicuous in the distance—mute and silent
memorials, amid the gray mists of the past, which read a lesson of
encouragement and comfort in a desponding and sorrowful present.
David thus trod the corridors of memory. When the future was dark
and louring, he surveys picture by picture, scene by scene, along the
chequered gallery of his eventful life! With Jordan at his feet, the
Hermon range in the distance, and some Mizar—some "little hill" (as
the word means)—rising conspicuous in view, he dwells on various
signal instances of God's goodness and mercy in connexion with
these localities—"I will remember Thee" (as it may be rendered)
"regarding the land of Jordan, and of the Hermonites, from the hill
Mizar."[59]
We know the other names to which he here adverts, but what is this
"hill Mizar?" The answer can only be conjectural. It may be some
small mountain eminence among the hills of Judah associated with
the experiences of his earlier days. May not memory possibly have
travelled back to the old home and valleys of Bethlehem, and lighted
perchance on the green slope where the youthful champion
measured his prowess with the lion and the bear. As the soldier
reverts with lively interest to his first battle-field, so may not the
young Shepherd-Hero have loved to dwell on this Mizar hill, where
the God he served gave him the earnest of more momentous
triumphs?
Or, to make one other surmise, may it more likely refer to "the little
hill" he most loved,—the home of his thoughts, the earthly centre of
his affections, the glory of his kingdom, the joy of the whole earth
—"Mount Zion, on the sides of the north, the city of the great King?"
[60]
We find Zion spoken of by him emphatically as "a little hill." In
one of the sublimest of all his Psalms, he represents the other loftier
mountains of Palestine,—Bashan with its forests of oak, Carmel with
its groves of terebinth, Lebanon with its cedar-clad summits,—as
looking with envy at the tiny eminence amid the wilds of Judah
which God had chosen as the place of His sanctuary: "Why look ye
with envy, ye high hills? this is the hill where God desireth to dwell
in; yea, the Lord will dwell in it for ever."[61] Is the hypothesis a
forced or unlikely one, that, in this his season of sore depression and
sorrow, he loved to linger on manifold experiences of God's
faithfulness associated with Zion,—its tabernacle, its festivals, its
joyous multitudes—his own palace, that crowned its rocky heights,
where his harp was oft attuned and his psalms composed and sung,
and in which midnight found him rising and giving "thanks to God
because of His righteous judgments?" In the mind of the Sweet
Singer of Israel, might not "glorious things" have been thought as
well as "spoken of thee, O city of God?"
But, after all, we need not limit the interpretation to any special
locality. The speaker's past history, from the hour when he was
taken from the sheepfolds till now, was crowded with Mizars—hill-
tops gleaming in the rays of morning. The valley of Elah, the wood
of Ziph, the forest of Hareth, the streets of Ziklag,[62] the caves of
Adullam and Engedi,—all would recall some special memorial of
God's delivering hand. He resolves to take the goodness and mercy
vouchsafed in the past, as pledges that He would still be faithful who
had promised to "David His servant," "My faithfulness and my mercy
shall be with him: and in my name shall his horn be exalted."[63]
"Thou who hast delivered my soul from death, wilt not thou deliver
my feet from falling, that I may walk before God in the light of the
living?"[64]
The saints of God, in every age, have delighted to dwell on these
memorable spots and experiences in their past pilgrimage. Abraham
had his "hill Mizar" between Bethel and Hai. "There," we read, "he
builded an altar, and called upon the name of the Lord."[65] On his
return from Egypt he retraced his steps to the same locality. Why?
Because it was doubly hallowed to him now, with these former
experiences of God's presence and love. It is specially noted that "he
went on his journeys from the south even to Bethel, unto the place
where his tent had been at the beginning, between Bethel and Hai;
unto the place of the altar, which he had made there at the first: and
[66]
THERE he called on the name of the Lord."

Jacob's "Mizar" would doubtless be his ladder-steps at Bethel, where


the fugitive wanderer was gladdened with a vision of angels, and the
voice of a reconciled God. Moses would think of his "Mizar" either in
connexion with the burning bush or the cleft of the rock, or the
Mount of Prayer at Rephidim. Isaiah's "Mizar" would be the vision of
the Seraphim, when his faithlessness was rebuked, and confidence
in God restored. Jeremiah tells us specially of his—some memorable
spot where he had a peculiar manifestation of God's presence and
grace. "The Lord hath appeared of old unto me, saying, Yea, I have
loved thee with an everlasting love: therefore with loving-kindness
have I drawn thee."[67]
Or shall we look to the New Testament? The Roman Centurion would
remember as his Mizar-height, the spot at Capernaum where
mingled Omnipotence and Love uttered the healing word. The
Magdalene would remember as hers, the Pharisee's banquet-hall,
where she bathed the feet of her Lord with a flood of penitential
tears. The Maniac of Gadara would recall as his, the heights around
Tiberias, where the demon-throng were expelled, and where he sat
calm and peaceful at the feet of the Great Restorer. The Woman of
Samaria would remember as hers, the well of Sychar, where her
Pilgrim Lord led her from the earthly to the eternal fountain. Peter
would remember as his, the early morn, and the solitary figure on
Gennesaret's shore. The Sisters of Lazarus, go where they might,
would recall as their hallowed memorial-spot, the home and the
graveyard of Bethany. Paul of Tarsus would ever remember as his,
the burning plain near Damascus, where a light, brighter than the
mid-day sun, brought him helpless to the ground, and a voice of
mingled severity and gentleness changed the persecutor into a
believer—the lion into a lamb. John, the beloved disciple, as he trod
the solitary isle of his banishment, or with the trembling footsteps of
age lingered in his last home at Ephesus—John would recall as the
most sacred and hallowed "Mizar" of all, the gentle bosom on which
he leant at supper!
And who among us have not their "Mizars" still? It has often been
said that, next to the Bible, there is no book so instructive as that
volume which all God's people carry about with them—the volume of
their own experience.
That is my earliest and fondest "Mizar," says one, the mother's knee
where I first lisped my Saviour's name, and heard of His love. Mine,
says another, is that never-to-be-forgotten sermon, when God's
messenger reasoned of righteousness, temperance, and a judgment
to come; when conviction was first flashed on my torpid mind, and
peace brought to my troubled soul! Mine, is another's testimony, is
that bed of sickness on which I awoke from the long life-dream of
indifference, and gave heed for the first time to the things which
belong to my peace. Mine, says another, is that chamber—that closet
of devotion—(alas! too long and guiltily neglected) hallowed and
associated with a renewed consecration to God, and with manifold
tokens of His grace and goodness. That hour of resisted temptation,
says another, is the "Mizar" on whose summit my stone of gratitude
is raised;—when I was trembling on the edge of some precipice, and
God's hand interposed and plucked me as a brand from the burning.
That awful bereavement is mine, says still another, which tore up my
affections by the root, and led me to seek in God, the heritage and
portion which no creature-blessing could bestow. It seemed at the
time to bode nothing but anger, but I see it now the appointed
herald of mercy sent to open up everlasting consolations. That
solemn death-bed is mine, says another, when I saw for the first
time the reality of gospel hope in the departing Christian, the sweet
smile of a foretasted heaven playing upon the lips, as if the response
to the angel-summons, "Come up hither!"
It is well for all of us, and especially in our seasons of depression
and sorrow, thus to retraverse life, and let our eyes fall on these
Mizar-hills of God's faithfulness. In seasons of spiritual depression,
when apt in our sinful despondency to distrust His mercy, and
question our own personal interest in the covenant;—when tempted
to say with Gideon, "If the Lord be with us, why has all this befallen
us?"—how encouraging to look back, through the present lowering
cloud, on former instances and memorials of Jehovah's favour, when
we had the assured sense of His presence; and with an eye resting
on these Mizar-hills on which He "appeared of old to us,"
disappointing our fears, and more than realizing our fondest hopes,
—to remember, for our comfort, that having "loved us at the
beginning," He will love us "even to the end!" If we can rest on one
indubitable token of His mercy in the past, let it be to us a
Covenant-keepsake, a sweet and precious token and pledge, that,
"though for a small moment He may have forsaken us," yet that
"with great mercy He will gather us," and that "with everlasting
kindness He will have mercy upon us."[68]
Why not thus seek, in the noblest sense of the word, to rise above
our trials, and perplexities, and sorrows, by taking the bright side of
things. There are two windows in every soul. The one looks out on a
dreary prospect,—lowering clouds, barren wilds, bleak, sullen hills,
pathways overgrown with rank and noxious weeds. The other opens
on what is bright and beauteous,—sunny slopes, verdant meadows,
luscious flowers, the song of birds. Many there are who sit always at
the former—gazing on the dark side of things, nursing their sorrows,
brooding over their trials. They can see nothing but Sinai and Horeb
—the trail of serpents and the lair of wild beasts. Others, with a
truer gospel-spirit, love, with hopeful countenance, to watch the
breaking of the sunbeam in the darkened sky. Like Paul, they seat
themselves at the bright lattice, saying, "Rejoice in the Lord alway,
and again I say, rejoice." Both look on identically the same
landscape. But the one descry only dull heaths and moors draped in
sombre hue. The others see these glorified with sunlight. The one
gaze on nothing but inky skies and drenching torrents. The others
behold the bow of heaven arching the sky, and the rain-drops
glittering like jewels on leaf, and grass, and flower. The one can
descry only "Hill Difficulties" and "Doubting Castles." The others love
to gaze on Hermons and Mizars, on "the Palace of the Beautiful,"—
the land of Beulah;—and, bounding the prospect, the towers and
streets of the Celestial City. They are ready to acknowledge that,
however many may have been their tribulations, their mercies are
greater and more manifold still;—that however many the shadowy
valleys, the bright spots outnumber the dreary.
Are any who read these pages cast down by reason of trouble, and
perplexity, and sorrow? Is God's hand lying heavily upon you—are
you in darkness, and in the deeps? Seek to lift the eye of faith to
Him. Seasons of trial must either bring us nearer to Him, or drive us
further from Him. It is an old saying, "Affliction never leaves us as it
finds us." It either leads us to "remember God," or to banish and
forget Him. How many there are (and how sad is their case) who,
when Providence seems to frown,—when their hearts are smitten
like grass, their cherished hopes blighted, their gourds withered,—
are led, in the bitterness of their spirits, to say, "My soul is cast down
within me. therefore, I will pine away in disconsolate sorrow. I will
rush to ruin and despair. My lot is hard, my punishment is greater
than I can bear;—all that made life happiness to me has perished;—
THEREFORE, I will harden my heart. I do well to be angry, even unto
death. Existence has no charm for me. I long to die—my only rest
will be the quiet of the grave!"
Sorrowing one! be yours a nobler philosophy. Look back from these
valleys of death and tribulation, to the gleaming summits of yonder
distant Mizar hills! Mark, in the past, the tokens and memorials of
unmistakeable covenant love. "Call to remembrance your song" in
former nights. Wounded Hart! on the hills of Gilead, forget not thy
former pastures. Go! stricken and smitten, with the tears in thine
eyes, bathe thy panting sides in the cooling "water-brooks." When
the disturbers of thy peace have gone, and when hushed again is
thy forest home, return to "the mountain of myrrh and the hill of
frankincense." Go, minstrel monarch of Judah, weeping exile! seat
thyself on some rocky summit on these ridges of Hermon, and,
surveying mountain height on mountain height, in the land of
covenant promise,—each associated with some hallowed memory,—
take down thy harp, and sing one of thine own songs of Zion. "Thou
who hast shewed me great and sore troubles shalt quicken me
again, and shalt bring me up again from the depths of the earth!"[69]
IX.
The Climax.
God of my life, to Thee I call,
Afflicted at Thy feet I fall;
When the great water-floods prevail,
Leave not my trembling heart to fail!"
"There is but a step from the third heavens to the thorn in the
flesh."—Winslow.
"Deep calleth unto deep at the noise of thy water-spouts: all thy
waves and thy billows are gone over me. Yet the Lord will command
his loving-kindness in the day-time, and in the night his song shall
be with me, and my prayer unto the God of my life."—Verses 7, 8.
IX.
THE CLIMAX.
The storm-struggle in the soul of the Psalmist is now at its height. In
the previous verse, he had penetrated through the mists of unbelief
that were surrounding him, and rested his eye on the Mizar hills of
the Divine faithfulness in a brighter past. But the sunshine-glimpse
was momentary. It has again passed away. His sky is anew darkened
—rain-clouds sweep the horizon—"Deep calleth unto deep at the
noise of thy water-spouts." Amid the environing floods he exclaims,
"All thy waves and thy billows have gone over me!"
The figure is a bold and striking one. Some have thought it has
reference to the sudden rush of water-torrents from the heights of
Lebanon and Hermon;—that it was suggested by the roaring
cataracts at his feet—Jordan with its swollen and winding rapids—the
faithful picture of the deep-worn channels in his own spirit—fretted
and furrowed with the rush of overwhelming sorrow.
But the word rendered "deep," is, in the original Hebrew, more
applicable to the floods of the ocean than to the rapids of a river;
and the image, in this sense, is bolder and more expressive still.[70]
Billow calls on billow to sweep over the soul of the sufferer. They lift
their crested heads, and with hoarse voice summon one another to
the assault. "Let us be confederate!" say they. "Let us rouse the
spirit of the storm! Let the windows of heaven be opened! Let the
fountains of the great deep be broken up, that we may shake this
man's confidence in his God, and plunder faith of her expected
triumph! Ye angry tempests, driving sleet and battering hail! come
and aid us. Ye forked lightnings, gleaming swords of the sky! leap
from your cloudy scabbards. Old ocean! be stirred from your lowest
depths. Let every wave be fretted to madness, that with one united
effort we may effect his discomfiture and leave him a wreck on the
waters!"
They obey the summons. Already chafed and buffeted, they return
with fresh violence to the shock. Affliction on affliction, temptation
on temptation, roll on this lonely, surf-beaten cliff. Outward
calamities—inward troubles; his subjects in revolt—his friends
treacherous; his own son and favourite child heading the
insurrection; he himself an exile, haunted with the thought of past
sins that were now exacting terrible retribution;—and worse than all
temporal calamities, the countenance of his God averted. Affliction
seemed as if it could go no further—"All thy waves and thy billows
have gone over me!"
We believe there are periods in the history of most of God's people
corresponding to the awful experience recorded in this verse. Few
there are who cannot point to some sad and memorable epochs
alike in their natural and spiritual being,—some solemn and critical
crisis-hours, in which they have been subjected to special and
peculiar trials;—encompassed with the thunders and lightnings of
Sinai—the trumpet sounding long and loud:—or, to revert to the
simile of the Psalm, when the moorings of life have been torn away,
and they have been left to drift, on a starless, tempestuous ocean.
Often, as with David, there may at such times be a combination of
trials,—sickness—bereavement—loss of worldly substance—
estrangement of friends—blighting of fair hopes. Then, following on
these, and worse than all, hard thoughts of God. We see the wicked
around prospering,—vice apparently pampered,—virtue apparently
trodden under foot,—many passing through life without an ache or
trial—their homes unrifled—their hearts unwounded—their every
plan prospering—fortune smiling benignantly at every turn; while we
seem to have been a target for the arrows of misfortune,—tempted
with Jeremiah to say, "I am THE man who have seen affliction by the
rod of His wrath."[71] And doubting a God of providence, the next
step is to doubt a God of grace. We begin to question our interest in
the covenant,—to wonder whether, after all, our hopes of heaven
have been a delusion and a lie. God's mercy we imagine to be "gone
for ever." He seems as if He would be "favourable no more." There is
no comfort in prayer—no brightness in the promises; the Bible is a
sealed book;—the heavens have become as brass and the earth as
iron! Oh, so long as we had merely external trials, we could brave
and buffet the surrounding floods. So long as we had the Divine
smile, like the bow in the cloud, resting upon us, we could gaze in
calmness on the blackest sky;—yea, rejoice in trial, as only unfolding
to us more of the preciousness of the Saviour. But when we have the
cloud without the bow,—when outer trials come to a soul in spiritual
unrest and trouble,—when we harbour the suspicion that the only
Being who could befriend in such an hour has Himself hidden His
face,—when we have neither this world nor the next to comfort us—
smitten hopes for time and despairing hopes for eternity!—this is the
woe of woes—the "horror of great darkness,"—"deep calleth unto
deep." We can say, with a more terrible emphasis far than the
smitten patriarch, "I AM bereaved!"
The Psalmist had now reached this extremity. It is the turning point
of his present experience. He has two alternatives before him:—
either to suffer unbelief to triumph, to distrust God, abandon the
conflict, and sink as lead in the surging waters; or to gather up once
more his spiritual resources, breast the waves, and manfully buffet
the storm.
It is with him now, as with a sinking disciple in a future age:—when
the storm is loudest and the midnight is darkest, the voice and
footsteps of his God are heard on the waves: "And about the fourth
watch of the night, Jesus came to the disciples, walking on the sea."
"This poor man cried, and the Lord heard him, and saved him out of
all his troubles!"[72]
And what is the first gleam of comfort which crests these topmost
waves? It is discerning the hand and appointment of God in all his
afflictions! He speaks of "Thy waves and Thy billows." These floods
do not riot and revel at the bidding of chance. "The Lord sitteth
upon the water-floods."[73] While, in one sense, it aggravated his
trials to think of them as Divine chastisements—the expressions of
the Divine displeasure at sin—yet how unspeakable the consolation
that every billow rolled at the summons of Omnipotence. "The
floods," he can say, "have lifted up, the floods have lifted up their
voice; the floods lift up their waves. The Lord on high is mightier
than the noise of many waters, yea, than the mighty waves of the
sea."[74] "O Lord our God, who is a strong Lord like unto thee? Thou
rulest the raging of the sea: when the waves thereof arise, thou
stillest them."[75]
But he could go further than this. He could triumph in the assurance
of God's returning favour;—that behind these troubled elements
there was seated a Being of unchanging faithfulness and love.
Already the lowering mist was beginning to clear off the mountains,
and the eye of faith to descry sunny patches of golden light
gleaming in the hollows. Soon he knew the whole landscape would
be flooded with glory. The sailor does not discredit the existence of
the beacon or lighthouse, or alter the direction of his vessel, because
the fog prevents these being seen. Nay rather, he strains his eyes
more keenly through the murky curtain, in hopes of hailing their
guidance. When a cloud or clouds are passing over the sun's disc,
and hiding it from view, the sunflower does not, on account of the
momentary intervention, hang its head, or cease to turn in the
direction of the great luminary. It keeps still gazing upwards with
wistful eye, as if knowing that the clouds will soon roll past, and that
it will ere long again be bathed in the grateful beams! So it was with
David. He felt that the countenance of his God, though hidden, was
not eclipsed. This pining flower on the mountains of Gilead does not
droop in the anguish of unbelief, when "the Sun of his soul" is for
the moment obscured. He knew that there would yet arise "light in
the darkness." Amid the roll of the billows—the moaning of the blast
—he listens to celestial music. Its key-note is "the loving-kindness"
of his God. While the heavens are still black, and the tempest raging,
he lifts the voice of faith above the war of the storm, and thus sings:
—"Yet the Lord will command his loving-kindness in the day-time,
and in the night his song shall be with me, and my prayer unto the
God of my life!"
"Yet the Lord!" The believer, even in his deepest and darkest season
of trouble, has always this alternative word—"Yet the Lord will!" I
am sunk in sore trial—"Yet the Lord" will be faithful to His promises!
I have been bereaved of those near and dear to me—"Yet the Lord"
will be to me a name better than that of son or daughter! I have
been laid for long years on this couch of suffering—"Yet the Lord"
has converted this lonely sick-chamber into the vestibule of heaven.
I have been tossed and harassed with countless spiritual temptations
—"Yet the Lord" will not suffer these temptations to go further than I
am able to bear. I am soon to walk through the dark valley—"Yet"
will "I fear no evil, for Thou art with me!"
The Psalmist's assurance of deliverance was indeed the test of no
meagre faith. We know well, how apt we are to be influenced and
affected by present circumstances. When all is bright, and genial,
and prosperous,—amid a happy home and kind friends,—in the
midst of robust health and flourishing worldly schemes, the buoyant
heart is full of elasticity. The joy without, imparts an inner sunshine.
A man is happy and hopeful in spite of himself. But if all at once he
is plunged into a vortex of trouble,—if clouds gather and thicken
around,—the mind not only becomes the prey of its own trials, but it
peoples the future with numberless imaginary evils, and its very
remaining joys and blessings become tinged and sicklied over with
the predominating sadness! It could as little be expected, on natural
principles, that the heart could in such circumstances be hopeful and
rejoicing, as to expect that the outer landscape of nature would glow
and sparkle with beauty, if the clouds of heaven obscured the great
fountain of light.
But faith, strong in God's word, can triumph over natural obstacles.
It did so in the case of this afflicted exile. He remembered how his
God had vouchsafed past deliverances, even when he least expected
them;—"They looked unto Him and were lightened"[76] [literally, "their
countenances were made bright."] He feels assured that the same
loving-kindness will be "commanded" still. He sees God's covenant
faithfulness resting calmly and beautifully, like the rainbow-tints in
the spray of the cataract! "Who is among you that feareth the Lord,
that obeyeth the voice of his servant, that walketh in darkness, and
hath no light? let him trust in the name of the Lord, and stay upon
his God."[77]
This experience we have been considering is that of Christ's people
only. But there is an experience sadder still: that of those who are
living "without God," and therefore "without hope;"—the billows
heaving, and yet they knowing not of them;—"deep calling to deep,"
yet they ignorant alike of their guilt and danger! There is nothing
more sad or touching in the midst of a storm,—when the vessel is
reeling on the waves, and little expectation of safety is left,—than to
see, amidst the settled gloom of despair, the little child playing on
the deck, all unaware of what is impending;—or, at a time of heart-
rending bereavement, when every face of the household is muffled
in sadness and suffused with tears, to hear the joyous laugh and
playful prattle of unconscious infancy. Ah! of how many is this the
position with regard to eternity;—living heedless of their danger—the
waves of destruction ready to close over them! Sadder far, surely, is
their case, than all the troubles and trials of God's most afflicted
people. Their waves and billows are crested with hope—"songs in
the night" come floating along the darkened surges; but the future
to the others has no ray of hope, no midnight star, no divine song!
There is a time coming when, in a more awful sense, the cry will be
heard, "Deep calleth unto deep: all Thy waves and Thy billows have
gone over me!" But there will be no after-strain—no joyous anthem
of anticipated deliverance—"Yet the Lord will command His loving-
kindness!" In vain will the cry ascend, "My heart is overwhelmed:
lead me to the Rock that is higher than I."
But, blessed be God, that cry may ascend now—that Rock may be
fled to as a shelter now. Sinner! these waves swept over the Rock of
Ages, that they might not sweep over you! Sheltered in these
crevices, you will be eternally safe. Not one blast of the storm, not
one drop of the rain-shower of vengeance, can overtake you. When
the billows of wrath—the deluge of fire—shall roll over this earth,
safe in these everlasting clefts, you may utter the challenge, "Who
shall separate me from the love of Christ?"
X.
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.

More than just a book-buying platform, we strive to be a bridge


connecting you with timeless cultural and intellectual values. With an
elegant, user-friendly interface and a smart search system, you can
quickly find the books that best suit your interests. Additionally,
our special promotions and home delivery services help you save time
and fully enjoy the joy of reading.

Join us on a journey of knowledge exploration, passion nurturing, and


personal growth every day!

ebookbell.com

You might also like