Antti Laaksonen Learning and Improving Algorithms
Total Page:16
File Type:pdf, Size:1020Kb
Undergraduate Topics in Computer Science Antti Laaksonen Guide to Competitive Programming Learning and Improving Algorithms Through Contests Second Edition Undergraduate Topics in Computer Science Series Editor Ian Mackie, University of Sussex, Brighton, UK Advisory Editors Samson Abramsky , Department of Computer Science, University of Oxford, Oxford, UK Chris Hankin , Department of Computing, Imperial College London, London, UK Mike Hinchey , Lero – The Irish Software Research Centre, University of Limerick, Limerick, Ireland Dexter C. Kozen, Department of Computer Science, Cornell University, Ithaca, NY, USA Andrew Pitts , Department of Computer Science and Technology, University of Cambridge, Cambridge, UK Hanne Riis Nielson , Department of Applied Mathematics and Computer Science, Technical University of Denmark, Kongens Lyngby, Denmark Steven S. Skiena, Department of Computer Science, Stony Brook University, Stony Brook, NY, USA Iain Stewart , Department of Computer Science, Durham University, Durham, UK ‘Undergraduate Topics in Computer Science’ (UTiCS) delivers high-quality instructional content for undergraduates studying in all areas of computing and information science. From core foundational and theoretical material to final-year topics and applications, UTiCS books take a fresh, concise, and modern approach and are ideal for self-study or for a one- or two-semester course. The texts are all authored by established experts in their fields, reviewed by an international advisory board, and contain numerous examples and problems, many of which include fully worked solutions. The UTiCS concept relies on high-quality, concise books in softback format, and generally a maximum of 275–300 pages. For undergraduate textbooks that are likely to be longer, more expository, Springer continues to offer the highly regarded Texts in Computer Science series, to which we refer potential authors. More information about this series at http://www.springer.com/series/7592 Antti Laaksonen Guide to Competitive Programming Learning and Improving Algorithms Through Contests Second Edition 123 Antti Laaksonen Department of Computer Science University of Helsinki Helsinki, Finland ISSN 1863-7310 ISSN 2197-1781 (electronic) Undergraduate Topics in Computer Science ISBN 978-3-030-39356-4 ISBN 978-3-030-39357-1 (eBook) https://doi.org/10.1007/978-3-030-39357-1 1st edition: © Springer International Publishing AG, part of Springer Nature 2017 2nd edition: © Springer Nature Switzerland AG 2020, corrected publication 2020 This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation, broadcasting, reproduction on microfilms or in any other physical way, and transmission or information storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now known or hereafter developed. The use of general descriptive names, registered names, trademarks, service marks, etc. in this publication does not imply, even in the absence of a specific statement, that such names are exempt from the relevant protective laws and regulations and therefore free for general use. The publisher, the authors and the editors are safe to assume that the advice and information in this book are believed to be true and accurate at the date of publication. Neither the publisher nor the authors or the editors give a warranty, expressed or implied, with respect to the material contained herein or for any errors or omissions that may have been made. The publisher remains neutral with regard to jurisdictional claims in published maps and institutional affiliations. This Springer imprint is published by the registered company Springer Nature Switzerland AG The registered company address is: Gewerbestrasse 11, 6330 Cham, Switzerland Preface to the Second Edition This second edition of the book contains several new sections that discuss advanced topics, such as calculating the Fourier transform, finding minimum cost flows in graphs, and using automata in string problems. I am grateful to Olli Matilainen for reading through most of the new material and giving many useful comments and suggestions. Helsinki, Finland Antti Laaksonen February 2020 v Preface to the First Edition The purpose of this book is to give you a comprehensive introduction to modern competitive programming. It is assumed that you already know the basics of pro- gramming, but previous background in algorithm design or programming contests is not necessary. Since the book covers a wide range of topics of various difficulty, it suits both for beginners and more experienced readers. Programming contests already have a quite long history. The International Collegiate Programming Contest for university students started during the 1970s, and the first International Olympiad in Informatics for secondary school students was organized in 1989. Both competitions are now established events with a large number of participants from all around the world. Today, competitive programming is more popular than ever. The Internet has played a significant role in this progress. There is now an active online community of competitive programmers, and many contests are organized every week. At the same time, the difficulty of contests is increasing. Techniques that only the very best participants mastered some years ago are now standard tools known by a large number of people. Competitive programming has its roots in the scientific study of algorithms. However, while a computer scientist writes a proof to show that their algorithm works, a competitive programmer implements their algorithm and submits it to a contest system. Then, the algorithm is tested using a set of test cases, and if it passes all of them, it is accepted. This is an essential element in competitive programming, because it provides a way to automatically get strong evidence that an algorithm works. In fact, competitive programming has proved to be an excellent way to learn algorithms, because it encourages to design algorithms that really work, instead of sketching ideas that may work or not. Another benefit of competitive programming is that contest problems require thinking. In particular, there are no spoilers in problem statements. This is actually a severe problem in many algorithms courses. You are given a nice problem to solve, but then the last sentence says, for example: “Hint: modify Dijkstra’s algorithm to solve the problem.” After reading this, there is not much thinking needed, because you already know how to solve the problem. This never happens in competitive programming. Instead, you have a full set of tools available, and you have to figure out yourself which of them to use. vii viii Preface to the First Edition Solving competitive programming problems also improves one’s programming and debugging skills. Typically, a solution is awarded points only if it correctly solves all test cases, so a successful competitive programmer has to be able to implement programs that do not have bugs. This is a valuable skill in software engineering, and it is not a coincidence that IT companies are interested in people who have background in competitive programming. It takes a long time to become a good competitive programmer, but it is also an opportunity to learn a lot. You can be sure that you will get a good general understanding of algorithms if you spend time reading the book, solving problems and taking part in contests. If you have any feedback, I would like to hear it! You can always send me a message to [email protected].fi. I am very grateful to a large number of people who have sent me feedback on draft versions of this book. This feedback has greatly improved the quality of the book. I especially thank Mikko Ervasti, Janne Junnila, Janne Kokkala, Tuukka Korhonen, Patric Östergård, and Roope Salmi for giving detailed feedback on the manuscript. I also thank Simon Rees and Wayne Wheeler for excellent collabo- ration when publishing this book with Springer. Helsinki, Finland Antti Laaksonen October 2017 Contents 1 Introduction .......................................... 1 1.1 What Is Competitive Programming? ..................... 1 1.1.1 Programming Contests ........................ 2 1.1.2 Tips for Practicing ........................... 3 1.2 About This Book .................................. 3 1.3 CSES Problem Set ................................. 5 1.4 Other Resources ................................... 7 2 Programming Techniques ................................ 9 2.1 Language Features ................................. 9 2.1.1 Input and Output ............................ 10 2.1.2 Working with Numbers ....................... 12 2.1.3 Shortening Code ............................ 14 2.2 Recursive Algorithms ............................... 15 2.2.1 Generating Subsets ........................... 16 2.2.2 Generating Permutations ....................... 17 2.2.3 Backtracking ............................... 18 2.3 Bit Manipulation ................................... 20 2.3.1 Bit Operations .............................. 21 2.3.2 Representing Sets ............................ 23 3Efficiency ............................................. 27 3.1 Time Complexity .................................. 27 3.1.1 Calculation Rules ............................ 28 3.1.2 Common Time Complexities .................... 30 3.1.3 Estimating Efficiency ......................... 31 3.1.4 Formal Definitions