Блог пользователя pllk

Автор pllk, история, 9 лет назад, По-английски

Competitive Programmer's Handbook is a new book on competitive programming, written by me. The book is still in progress but almost ready, and I decided to release it now for a wider audience.

You can download the book here:

https://cses.fi/book.html

The book consists of 30 chapters and is divided into three parts. The first part discusses basic topics such as programming style, data structures and algorithm design. The second part deals with graph algorithms, and the third part introduces some more advanced techniques.

The book assumes that the reader knows the basics of programming, but no background on competitive programming is required. I think that the book is useful for future IOI participants, as the book covers most topics in the IOI syllabus.

The final version of the book will be ready later this year. The PDF version of the book will be available for free also in the future, and in addition, there will be a printed version that will cost something.

Before the final version, I will do small fixes, improve the language and add references. Of course, I appreciate all feedback on the book — you can send it to this blog or directly to me.

  • Проголосовать: нравится
  • +1161
  • Проголосовать: не нравится

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +6 Проголосовать: не нравится

YOU HELPED IN A GREAT WAY ____///////////////\\\\\\\\\\\________ A BIG SALUTE

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +10 Проголосовать: не нравится

Good job!

»
9 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится +13 Проголосовать: не нравится

I love it :) But I think you can add more problems , and more advanced topics too

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +10 Проголосовать: не нравится

Are certain sections highlighted at the start of the section that its exclusively for ICPC participants? So that those aiming for IOI may not go in much deep! Thank you Keep up the good work

  • »
    »
    9 лет назад, скрыть # ^ |
     
    Проголосовать: нравится +14 Проголосовать: не нравится

    At the moment there is no such classification, but it might be a good idea. However, new topics are regularly added to the IOI syllabus, so it is difficult to say what is needed in future years. I also think that all topics in the book are worth learning, even if they are not in the IOI syllabus at the moment. :)

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +33 Проголосовать: не нравится

Logged in just to Upvote this blog and say thank you to pllk. Great job :)

»
9 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится +17 Проголосовать: не нравится

Thank you! I think it is a really good book with very focused content. Just a suggestion, maybe you could include some competitive programming tricks into your book? For example, how to write a shortened version of a common algorithm (e.g. union-find can be written in 4 statements without using union-by-rank heuristic and is still good enough in competitions)?

  • »
    »
    9 лет назад, скрыть # ^ |
     
    Проголосовать: нравится +9 Проголосовать: не нравится

    You are right, I should at least mention the other heuristic. I have used the union-by-size heuristic, because I think it is both easy to code and explain why it works in logarithmic time.

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +10 Проголосовать: не нравится

Thank you for sharing. The book is well written. Definitely a plus!

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +10 Проголосовать: не нравится

Very useful and well written :)

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +90 Проголосовать: не нравится

Wow, this looks like a tremendous amount of work. I'm really curious about a few things.

How long did it take you? How old are you and are you a teacher? Have you written it in your free time, without the money compensation from e.g. university?

  • »
    »
    9 лет назад, скрыть # ^ |
     
    Проголосовать: нравится +170 Проголосовать: не нравится

    Good questions. I'm 29 now and I teach (among other things) at university.

    It has been a long project, I started it in about 2013. First I wrote the book in Finnish (and rewrote it several times because I was not satisfied), and finally I decided to translate it into English (because most people can't read Finnish).

    It is my free time project without salary, this is also one reason why it took so long time. But I've learned a lot, both about competitive programming and writing.

»
9 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Brother its fantastic. I salute you.

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +18 Проголосовать: не нравится

I think this may be the best competitive programming book for beginners, I've ever seen! I've read some of Competitive Programming by Steven Halim already, and I would say that it is indeed a good book. However, truth be told I don't think it is necessarily beginner friendly. The way the sample code is written makes it somewhat difficult to read at times. Personally, I didn't know much C++ when I started to read it so the constant one-liner "if" and "for" statements he often uses obscured the meaning behind a lot of algorithms, for a few weeks, at times. So the clean code in your book is a huge plus.

One reason I can see this book being the best beginner book is that you "spell out" everything for the reader. I read the chapter on bit manipulation and I certainly believe it is the most well-written piece of literature on it I've ever seen. I don't think I've ever seen a coherent article written on using bitmasks for DP problems written for beginners either, and I can't wait to sink my teeth into the remainder of the book.

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +8 Проголосовать: не нравится

Awesome Work !! You can add some related problems in each chapter.

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +67 Проголосовать: не нравится

If you share the book sources, the community can translate it to other languages.

»
9 лет назад, скрыть # |
Rev. 7  
Проголосовать: нравится +59 Проголосовать: не нравится

I read some prefix of the book

It's easy to read (but I didn't find anything new yet but that's pretty normal I suppose)

What I want you to consider is to promote a cleaner code. I think it's quite important especially when there are more than 1 coder in a team (but i find it useful even when I participate in personal contest)

What I mean, for example:

  • When discussing defines for cycles, you may discuss pros and cons (e.g typing speed vs readability and harder to spot errors) (how your FOR will work when iterating from 10^10 to 10^10+5 ?)
  • I find 1-indexed arrays very questionable
  • (that's more debatable) binary search in my opinion is more handsome when formulated in terms of invariant f(l) = true, f(r) = false:
while(r - l > 1) {
   int m = (l + r) / 2;
   if (f(m)) {
      l = m;
   }
   else {
      r = m;
   }
  • fixed size arrays (e.g in graph representation)
  • understandable names (e.g array of used vertices in dfs)

By the way, You explain how to sort vector before introducing what it is, so may be it's worth moving sorting chapter after the introduction of vector because or at least say something like if you don't know what it's don't worry, you'll know in the next section.

»
9 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится +6 Проголосовать: не нравится

I've noticed that you add pairs t vector using v.push_back({1, 2}) and v.push_back(make_tuple(1, 2, 3)). I believe, braces initialisation should work for tuple too (and also you may use emplace_back) in either case

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +5 Проголосовать: не нравится

A very well resourceful book.

»
9 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится +30 Проголосовать: не нравится

Thanks a lot for the effort :) I think it would be great if you can add interesting sample problems for each topic and also add some more advanced techniques and algorithms. By the way, I would love to donate and to translate it into Turkish.

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +10 Проголосовать: не нравится

Thank you very much for your efforts. I literally learned more today than I did for the last month.

»
9 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Surely great amount of work. But it will great if you add problem to practice section after every chapter of your book.

»
9 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Wonderful book, and I think I'll use it often. But I do feel some important topics are missing. Perhaps they could be added into later editions? This could be another of the aspects where the codeforces community could help.

Topics that come to my mind would be fast exponentiation and its applications to DP, along with other dp optimizations like Knuth or convex hull trick, etc.

»
9 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится +8 Проголосовать: не нравится

Method 2 for binary search would be cleaner if you change b = n/2 to b = (n+1)/2 and b /= 2 to b = (b + 1) / 2. This way you don't need the while loop.

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +17 Проголосовать: не нравится

People like you , are a blessing for the entire coding community .. :) Thanks a lot :)

»
9 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

If you add some problem name from different oj in each section . It will be more helpful .

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +10 Проголосовать: не нравится

хорошая книга

»
9 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Thanks pllk, great work, and really amazing coverage of many topics, it would be really helpful to add some practice problems from OJs.

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +7 Проголосовать: не нравится

As it turns out, a lot of people are asking for practice problems. So I propose that you guys create a Wiki and make some top rated people willing to contribute an admin of the wiki. Anyone can add problems / editorials here and it will be approved if and only if the quality of the problem / editorial is high enough and actually helps someone to improve their skills.

  • »
    »
    9 лет назад, скрыть # ^ |
    Rev. 2  
    Проголосовать: нравится +58 Проголосовать: не нравится

    I don't see why pllk should be obliged to create this wiki. He has done more than enough already by just creating this book and I think the people asking for problems are, more or less, missing this purpose of this book. The book is entitled "Competitive Programmer's Handbook". In my opinion, it seems like a book for beginners to get their feet wet, and understand concepts and aspects of implementation in the process, and for intermediate people to use it as a reference manual when solving problems.

    The second reason why I'm against this idea of putting problems in the book is that there are more than enough posts on codeforces with titles such as "What are some good problems involving segment trees" or whatever, and I don't see how it is any at all difficult to simply search for them on the site. I mean just look here, here, and on the entire section of Hackerrank about data structures and algorithms, for instance. Since, this post came to my attention, it has become somewhat easier, or at least more straightforward to read the Competitive Programming book, since I can always use the handbook here as a reference for more "difficult" concepts.

»
9 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Thanks a lot brother.

»
9 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

I haven't understood this line. Please someone explain me this line. In 2.2 Compexity Classes

A special property of square roots is that sqrt(n) = n/sqrt(n), so the square root sqrt(n) lies, in some sense, in the middle of the input.

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится

I've gone through the "Advanced Topics" part and my reaction while reading this book can be described as: wow wow wow wow wow wow.....

Thank you for sharing it.

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +6 Проголосовать: не нравится

Thanks loads n loads.

Here is a book I wish I would have got earlier. Went through graph portion. For the first time, I felt dfs, bfs, bellman, Dijkstra are reachable and can be coded.

So kind of you that you have kept it free for all. I will advice this if someone wants to enter competitve programming.

Thanks again. A big hug.

»
9 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Love the book, especially the advanced topics section, which includes most of the material needed to become a mid-purple.

»
9 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

THANKS SIRRR !!!!!

»
9 лет назад, скрыть # |
Rev. 19  
Проголосовать: нравится 0 Проголосовать: не нравится

Your book is awesome. Thanks.

»
9 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

thanks and gratitude

»
9 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Thank you very very very much!

»
9 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Thank you for such an amazing book! Im wondering if theres an available epub version of this book?

»
9 лет назад, скрыть # |
Rev. 5  
Проголосовать: нравится +18 Проголосовать: не нравится

In page 259, chapter 29: Geometry, I think it should be:

P a = {4,2};
P b = {3,-1};
cout << abs(b-a) << "\n"; // 3.16228

Instead:

P a = {4,2};
P b = {3,-1};
cout << abs(b-a) << "\n"; // 3.60555

Using the formular, we got:

»
9 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

You can add Bertrand's postulate to number theory chapter:

There are at least one prime p such that n < p < 2n where n > 1.

»
9 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

Can someone please send me the code for K-th ancestor in a successor graph. I have understood the algorithm but still not clear about writing the code. Thanks in advance.

»
9 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

A really nice resource, appreciate it.

»
9 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится +3 Проголосовать: не нравится

OH my go-----------d!!! This is really an excellent book for a beginner like me. People learn from each other, share with each other and inspire each other. This is how the world develops generation by generation. I think this world needs people like you. With great power comes great responsibility!! Thank you so much for your invaluable contribution!!

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится

This is #1 on HN right now: Thread. There's a bunch of feedback so I thought you should know. :)

  • »
    »
    9 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    Lots of people there really don't like competitive programming, sad!

    • »
      »
      »
      9 лет назад, скрыть # ^ |
      Rev. 2  
      Проголосовать: нравится +11 Проголосовать: не нравится

      Competitive programming threads on most sites seem to degenerate into technical interview bashing.

    • »
      »
      »
      9 лет назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится

      You can understand them :)

      cp code:

      in m;
      cin>>m;
      VI a(m);
      forn(i,m)
        cin>>a[i];
      sort(all(a));
      prv.resize(m);
      VVI isp(mxpp,VI(mxpp*mxsc));
      

      Real life code:

      var maybeVCenterConnectionSettings = connectionSettingsDialog.ShowDialogEx();
      
      await maybeVCenterConnectionSettings.ApplyAsync(async connectionSettings =>
      {
          var gridEntryInConnectingState = VCenterConnectionDescriptor.CreateInConnectingState(
              infrastructureAddress: connectionSettings.Address);
      
          AddGridEntry(gridEntryInConnectingState);
      
          (await _serviceProvider.ConnectionsManager.AddConnectionAsync(connectionSettings))
              .OnSuccess(endpointDescriptor => AddGridEntry(endpointDescriptor))
              .OnFailure(processServiceError: ShowServiceRequestFailure);
      });
      
»
9 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Hey @pllk, thank you very much! By the way, do you have the printed version available for purchase? I would love to buy this book.

»
9 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится +3 Проголосовать: не нравится

hey pllk

thank you very much for your awesome work

your book was very helpful to me

i'm using it to train for the IEEEXtreme programming competition

which — by the way — will be on October the 14th .

so if i may ask you ... will your book be ready before the competition or not ?

»
9 лет назад, скрыть # |
Rev. 7  
Проголосовать: нравится +8 Проголосовать: не нравится

How can the complexity of Bellman-Ford algorithm implementation in the book be O(N.M) ? shouldn't this code be O(N^2.M) UPDATE: O(N^2.NM) ? (Although the real algorithm complexity is O(N.M) !)

Book page : 123

»
9 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Does the book talk about how to problem solve?

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +3 Проголосовать: не нравится

In the greedy Section Minimizing sums
there are a solution for this:
Minimize (a1-x)^2 + (a2-x)^2 + (a3-x)^2 .... (an-x)^2
And the solution is x = (average (Ai) )
That is because the average is the avarage of the
polynomial roots from nx^2 -2x(a1+a2+...+an)

Someone could explain me why works please??
How prove this??
And it works for every power different to 2?

»
9 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

...

»
8 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

I have already try to learn CP through some famous books but that books are either difficult or no code in C++ illustration. Thank you very much. A good book for me, also beginners who start to learn CP.

»
8 лет назад, скрыть # |
 
Проголосовать: нравится +3 Проголосовать: не нравится

Great work! I'm trying to translate into Japanese.

It's WIP and I completed until Ch.8. https://github.com/kmjp/cphb

»
8 лет назад, скрыть # |
 
Проголосовать: нравится +8 Проголосовать: не нравится

Every book has a nice cover. This book is excellent. It deserves a nice and cool cover!

Would be interesting to have ideas for a book cover. So, let the ideas flow in!

»
8 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

Very good stuff. Good job!

»
8 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

My review on this book:

EVERY F*CKIN' ALPHA-NUMERIC CHAR WORTH

»
8 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

pg. 266, draft Dec 2017, discussing a general formula for the area of arbitrary quadrilaterals, you give the shoelace formula for which 'there are no special cases'.

However, the shoelace formula gives negative area if vertices are given in clockwise order, so you may want to add absolute value signs around the formula if you want 'no special cases'.

»
8 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

13.1 Bellman–Ford algorithm

I think the graph in your example should be directed, see this answer. Thank you.

»
7 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

It would be great if someone shares an ideal 20-page Cookbook for ACM ICPC Regional.

»
7 лет назад, скрыть # |
Rev. 3  
Проголосовать: нравится +22 Проголосовать: не нравится

Your iterative union-find find function doesn't flatten the tree, making it slow on average, you have:
int find(int x) { while (x != link[x]) x = link[x]; return x; }
You should use a recursive one which flattens it:
int find(int x) { if (x == link[x]) return x; return link[x]=find(link[x]); }

»
7 лет назад, скрыть # |
 
Проголосовать: нравится +5 Проголосовать: не нравится

Thanks for your work.

»
7 лет назад, скрыть # |
 
Проголосовать: нравится -6 Проголосовать: не нравится

Here's the link for the online version of the book.

Competitive Programming

»
7 лет назад, скрыть # |
Rev. 4  
Проголосовать: нравится 0 Проголосовать: не нравится

EDIT: My bad, if (S&(1<<k))>0 then partial(S^(1<<k),k)==partial(S^(1<<k),k-1), as S^(1<<k) has kth bit not set, so the k iteration didn't do anything so it's same as (k-1) iteration.

PRE-EDIT: Once again a great book! On page 105, you show the recurrence of partial(S,k) = partial(S, k-1) + partial(S^(1<<k), k-1), but that last term seems to be partial(S^(1<<k),k) in your code on the next page since you use only one array sum, and S^(1<<k) is smaller than S, so it is already calculated for k, not k-1. Which is right here?

»
7 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Is the final version of the book available? pllk

»
5 лет назад, скрыть # |
 
Проголосовать: нравится +3 Проголосовать: не нравится

I really appreciate your help. Thank you.