Competitive Programming 2 2nd Steven Halim download
Competitive Programming 2 2nd Steven Halim download
download
https://ebookbell.com/product/competitive-programming-2-2nd-
steven-halim-4723160
https://ebookbell.com/product/competitive-programming-4-book-2-4th-
steven-halim-felix-halim-46668794
https://ebookbell.com/product/competitive-programming-4-book-2-4th-
edition-steven-halim-felix-halim-46829310
https://ebookbell.com/product/competitive-programming-4-the-lower-
bound-of-programming-contests-in-the-2020s-4th-edition-steven-
halim-46503294
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
https://ebookbell.com/product/competitive-programming-3-the-new-lower-
bound-of-programming-contests-3rd-steven-halim-10205022
https://ebookbell.com/product/competitive-programming-guide-learning-
and-enhancing-algorithms-with-contests-bharat-mishra-55749594
https://ebookbell.com/product/competitive-programming-4-book-1-4th-
steven-halim-felix-halim-46668790
https://ebookbell.com/product/competitive-programming-4-book-1-4th-
edition-steven-halim-felix-halim-46829276
Contents
Foreword v
Preface vi
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
i
CONTENTS
c Steven & Felix
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
iii
CONTENTS
c Steven & Felix
B uHunt 225
C Credits 227
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.
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.
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
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!
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.
• 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
• 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.
• 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
• ≈ 550 buyers of the 1st edition as of 1 August 2011. Your supportive responses encourage us!
• 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.
x
CONTENTS
c Steven & Felix
Authors’ Profiles
Steven Halim, PhD1
stevenhalim@gmail.com
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
// 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
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
xiii
List of Tables
xiv
List of Figures
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
xv
LIST OF FIGURES
c Steven & Felix
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
xvi
Chapter 1
Introduction
Illustration on solving UVa Online Judge [28] Problem Number 10911 (Forming Quiz Teams).
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
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.
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:
#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
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
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.
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.
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.
To be competitive, you must frequently classify the problems that you read in the problem set into
type A (or at least type B).
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).
• Perform amortized analysis (see [3], Chapter 17) – although rarely used in contests.
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!
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:
• 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.
• 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?
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?
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?
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) 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.
(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.
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;
3
0.1227...
0.517611738...
0.7341231223444344389923899277...
#include <cstdio>
using namespace std;
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;
}
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.
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?
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 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
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.
• 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
• (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
• 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 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
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
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
• 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.
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
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
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).
22
2.2. DATA STRUCTURES WITH BUILT-IN LIBRARIES
c Steven & Felix
• 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).
7. To get the first bit that is on (from right), use T = (S & (-S)).
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).
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
• 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.
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.
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!
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.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.
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.
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:
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?
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.
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.
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;
} }
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);
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;
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.
—Cowper.
ebookbell.com