SecondThread's blog

By SecondThread, 3 weeks ago, In English

Algo Talk

Good morning everyone! Errichto and I each just released new videos in which we discuss some cool problems:

Please check them out and let us know what you think. More will be coming soon!

Read more »

  • Vote: I like it
  • +329
  • Vote: I do not like it

By SecondThread, history, 6 weeks ago, In English

Algorithms Thread Episode 8: Tree Basics

Episode 8 of Algorithms Thread comes out in <90 minutes! This one is a bit more beginner-friendly and covers the following ideas:

  • Graph/Tree Diameters
  • Binary Lifting
  • Tree Flattening with Euler tours

Also, to make sure you have actually learned that stuff, I made a custom Gym set on CodeForces that will last two weeks that hopefully is really good practice for making sure you have learned this stuff. Here is a link to the gym set; it will be available 45 minutes after the video comes out so that people have time to watch the video before starting the set, if they are interested in penalty points. All of the problems in the gym are original to this set (in their flavortext at least, some are simple enough that I'm sure they have appeared in other contests before).

The new gym integration was heavily inspired by Errichto's Matrix Expo set format. Let me know whether it's helpful. I think it might be, but also it's a pretty big time commitment to make it, so whether I keep doing them depends on how helpful they are to people.

If you have any questions or suggestions, feel free to leave them below. I hope you enjoy the problem statements, and I'll leave you all with this:



Read more »

  • Vote: I like it
  • +1924
  • Vote: I do not like it

By SecondThread, history, 7 weeks ago, In English

Brookfield Computer Programming Challenge (BCPC)

Hi everyone!

TLDR: Speedrunnable contest here, bad solution videos + original standings here.

Last week I learned how to use Polygon, so I uploaded and regenerated data/solutions to the first contest I ever wrote, and uploaded it to the gym. The final score of the original contest is available here. In the original contest, the last problem was only unlocked after solving everything else (which no teams did). Originally this was a set for high school students in Wiscosin, but I thought some people here might enjoy speedrunning it.

Solution videos are also available here. They aren't very good because I was a young child when I made them, but they should at least convey the main ideas pretty well. The one interesting thing to mention is:

For problem LAST Robotics:


I hope you enjoy! Let me know if there are any technical issues, because those may indicate that I've set something up incorrectly, which was kind of the main thing I was trying to avoid here.

Read more »

  • Vote: I like it
  • +21
  • Vote: I do not like it

By SecondThread, 7 weeks ago, In English

TLDR: Stream at this time! See you there!

Hi everyone! I very recently reached 1<<12 subscribers on Youtube! To celebrate, I'm going to be doing my first ever livestream! I'll be on Youtube only this time (maybe I'll do both youtube and twitch later if there's demand for it). The stream will include looking at and trying to solve Code Jam Finals problems, which will be going on at the same time. In general, live-streaming participation in a contest is considered cheating and is very bad. Do not do this for any public contests!

To be careful not to leak solutions or anything:

  1. I will significantly delay my start of the round.
  2. I will spend the beginning of the contest (where my participation overlaps with the real thing) reading all problems instead of solving.
  3. I will not explain solution ideas of any problems until the round is over.

That way, this isn't any more revealing than the ICPC NAC Livestreams which present solution sketches to easy and medium problems on the stream and expect the small number of participants to be honorable. Besides, if a finalist actually wanted to be a bad sport, there are much better ways than trying to get some tiny amount of info from me. (I won't give ideas here, but I'm sure you can think of some)

Cool, hopefully I'm morally redeemed! I'll also be doing some other stuff, unrelated to Code-jam, like upsolving problems from the Div2, answering random questions if people have them, and maybe even setting up some stuff for a super-cool open source project that I know Codeforces will be hyped about!

I'll start streaming at whatever this time is for you on my Youtube channel SecondThread. Hope to see some of you there!

Update: Tech check went well, see everyone soon!

Read more »

  • Vote: I like it
  • +148
  • Vote: I do not like it

By SecondThread, history, 3 months ago, In English

Unrated Account Disaster

Recently there have been an obscene number of unrated accounts showing up. Several of them have inappropriate names, so I won't give examples because I want to keep this post clean, but I'm sure you have seen them in the comments. They are likely all by the same individual, possibly with a few copy-cat troublemakers as well.

Recently, certain ones have begun to spam useless comments on old posts to clog up the recent actions, effectively hiding all relevant conversations except on the blog posts they spam on. For whatever reason, these are overwhelmingly on Errichto's old blog posts. Occasionally there are also a flood of obscene blog posts made by the user themselves.

Here's an example of what I mean:

This is obnoxious and I would like to see it stop.

The current solution clearly doesn't work. As soon as they get banned or muted or whatever, they can just make another throw-away account and continue spamming tomorrow.

A slightly less extreme problem is that lots of new users have created alt accounts in order to ask fairly meaningless 'How do I get better', 'please solve this problem for me', et cetera type of questions.

Suggested Solution

Make it so that users who haven't competed in any contests don't have permissions to post blogs or comments. At the very least, this should deter a lot of these fake accounts from being created.

What about legit accounts who don't compete?

I know there are a few accounts used by companies/media which are used for public announcements, for instance: NercNews. In cases like this, if it is actually a legitimate news source, we can 'trust' these users with the GM 'trust this user' feature. As far as I know, there aren't really that many accounts like this that are run by large companies/media organizations. I think each of them should be able to find at least one GM who is either a part of the organization or can verify that the organization is trustworthy enough to not intentionally spam Codeforces.

Do you agree? If so, can you please tag some people who would have the ability to fix this so that this post actually gets noticed within the haystack of worthless spam?

Read more »

  • Vote: I like it
  • +761
  • Vote: I do not like it

By SecondThread, history, 3 months ago, In English

AlgorithmsThread Episode 7: All Point Pairs

Hi everyone! I just published Episode 7 of AlgorithmsThread, which talks about processing all pairs of points, while keeping the rest of the points sorted in a helpful way. I talk about the following problems in it:

  • Biggest Triangle in a set of points
  • Smallest Triangle in a set of points
  • Number of pairs of non-intersecting triangles
  • Minimum Area Quadrilateral in a set of points

I find this to be a really helpful trick that isn't super well known, so feel free to check it out if any of these sound like things you want to learn!

Problem Links:

Feel free to post any questions below!

Read more »

  • Vote: I like it
  • +145
  • Vote: I do not like it

By SecondThread, history, 3 months ago, In English

Deleting Comments

Recently I have noticed several of my comments end up deleted. I don't think my comments were unhelpful, spammy, or otherwise something that shouldn't be seen. In fact, I'm quite confident that the reason they aren't there anymore is because the are children in the reply tree to some comment that was deleted earlier up the chain (and it was that comment that was unhelpful or could otherwise be deemed inappropriate).

Here are two examples:

There are some other examples as well of similar nature.

Why/how is it happening?

Who is making these decisions, and on what criteria? To me it isn't obvious. Are there just some special users who have the ability to delete other people's stuff? Is that an IGM/LGM privilege that I just haven't earned yet? Is Mike manually deleting rows in some SQL database every time this happens?

Why subtree delete?

In lots of these cases, I remember interesting and valid things being said by myself and others that are no longer visible. Is it intentional to delete the entire subtree of comments rather than just the egregious one(s)? I suppose for the case of deleting blogs it may be a different story; I can imagine technical difficulties that would arise when trying to hide a blog, but not its comments. But what about comment subtrees?

Read more »

  • Vote: I like it
  • +196
  • Vote: I do not like it

By SecondThread, history, 3 months ago, In English

AlgorithmsThread 6: Convex Hulls

Hi everyone! I just released Episode 6 of AlgorithmsThread (now rebranded from Algorithms Dead after frodakcin's epic suggestion).

In it, I talk about:

  • Getting the convex hull
  • Checking if a point is in a convex hull in $$$O(log(n))$$$
  • Finding the farthest point in some direction in $$$O(log(n))$$$
  • The problem Trash Removal with $$$O(n^3)$$$ -> $$$O(n^2)$$$ -> $$$O(n*log(n))$$$ solutions
  • The more difficult problem Troop Mobilization from ICPC South East Regionals

I hope you enjoy. Feel free to ask questions below, as usual :)

Read more »

  • Vote: I like it
  • +229
  • Vote: I do not like it

By SecondThread, history, 3 months ago, In English

AlgorithmsThread 5: Persistent Data Structures

Hello everyone! I just uploaded Episode 5 of Algorithms Dead in which I talk about persistent data structures. I talk about the ASC problem involving a persistent queue, describe how persistent segment trees work, and provide some interesting problems that can be solved and then optimized with persistent segment trees.

Some problems discussed in this video if you are interested in solving them yourself:

Harder PST problems (not covered in the episode but good practice):

Let me know if you have any questions of suggestions for how I can improve the series!

Read more »

  • Vote: I like it
  • +166
  • Vote: I do not like it

By SecondThread, history, 3 months ago, In English

CF Notifications

Want an easy-to-use tool to notify you when you get a problem correct? Looking for an inspirational jingle to celebrate when you AC? Wish you could just move on to problem B immediately after submitting A and had someone to let you know in case you got it wrong? Now you can! is a simple website that does this for you. All you have to do is type in your handle and click login.

It works on all CF rounds, and also other submissions if you are upsolving, practicing, or running a VP on your own. Personally, I just leave it on a second computer with the volume turned up and then I don't have to worry about it ever.

How it works

It rechecks Codeforces every 4 seconds for new submissions, or every 1 second if you have a submission that is judging. It uses the CF API and I did my best to make sure it is as low-impact to the servers as possible while still giving results pretty much instantly.

Let me know what you think!


  • Per request, I added the ability to play a custom sound on AC (or play no sound at all). The changes are live now, so you should be able to see, but basically now you can enter 'none' if you just want the notification that you got the problem right and no 'distracting' inspirational sound effect, or something like '' if you want to hear 3 minutes of Stacy's Mom every time you solve a problem!

  • I also made it save your handle (and the custom sound if you choose to use one) as a cookie, so it should be even easier to use. If you have been there before, everything will auto-fill so you can literally just click the button and it's working.

Read more »

  • Vote: I like it
  • +197
  • Vote: I do not like it

By SecondThread, history, 3 months ago, In English

AlgorithmsThread 4: Segment Tree Beats

Segment Tree Beats are a really cool, and fairly advanced, modification you can make to segment trees in order to handle range-min-with queries. I talk about what they are and why they work in Episode 4 of AlgorithmsThread.

Feel free to comment any questions about what I covered in the comments of this blog, and I'll answer them as soon as I get a chance to.

Other Resources

Read more »

  • Vote: I like it
  • +144
  • Vote: I do not like it

By SecondThread, history, 3 months ago, In English

Viewing Past Contests

It would be really nice to be able to see past CF contests in the Contests tab. Usually they show up below the upcoming contests, but since the ICPC Practice is running for like 2 days straight, we can't see them.

For me it is just an annoying inconvenience because I can get there through my submission history. But if I wanted to VP a previous round for instance, there isn't really a good way of doing that without a link (or if there is a good way, I don't think it is very clear what that way is).

Possible Solutions

For long contests (ICPC Challenge, Microsoft Q#..., et cetera), it would be nice to still be able to see old contests in the contests list. I can understand if it would be too much of a server load for CF rounds, but these contests likely have much lower participation and are less demanding.

Read more »

  • Vote: I like it
  • +23
  • Vote: I do not like it

By SecondThread, history, 3 months ago, In English

AlgorithmsThread Episode 3: Segment Trees

Hi everyone, I just made Episode 3 of AlgorithmsThread. This one is a bit easier than usual and covers Segment Trees. At the end of the video, I talk about an interesting and difficult Segment Tree problem called Sneetches, that might be worth reviewing if you already know your segment trees quite well.

This video is a bit easier because the next two will be about some hard segment tree topics, and this should help prevent people who don't know segment trees yet from getting completely lost.

If you have any questions on stuff I covered, the comments below is a great place for them!

Update: Problem Links

Read more »

  • Vote: I like it
  • +247
  • Vote: I do not like it

By SecondThread, history, 3 months ago, In English

Algorithms Dead Episode 2: RMQ Tricks

Episode 2 of Algorithms Dead is out now! In it, I talk about:

  • How to find the min in a range of an array on O(1)
  • How to build an RMQ in O(n)
  • How to use an RMQ to find the lowest common ancestor in a tree

If you're new to these ideas, or looking for a refresher, it might be worth checking out. If you have questions, feel free to post them below instead of DMing me, so that other people with the same questions can see the answers.

Further Reading

brunomont and tfg showed me their fantastic (and recently published) blog post here: This didn't influence this episode or anything (my stuff was based on jcg's comment on this post from 7 months ago), but brunomont does a great job benchmarking this against segtrees, so definitely go upvote his post for his hard work!

Read more »

  • Vote: I like it
  • +181
  • Vote: I do not like it

By SecondThread, history, 3 months ago, In English

Algorithms Dead Episode 1: Division Under Mod

Do you blindly do operations under mod without knowing why they work? Does it scare you when a problem asks you do print something mod a big number? If so, you should watch Episode 1 of Algorithms Dead!

In it, I talk about why mod operations (addition/subtraction/multiplication) are allowed, why mod inverses work, and what things are safe to do when you store fractions as $$$p*q^{-1}$$$.

Read more »

  • Vote: I like it
  • +144
  • Vote: I do not like it

By SecondThread, history, 4 months ago, In English

Episode 0 of Algorithms Dead is out now! It covers the Hungarian algorithm and how to do dijkstra's in just v^2 instead of e*log(e). Usually e*log(e) is fine, but v^2 is obviously faster on a complete or nearly-complete graph.

Other than recording where my mouse is so you can see what I am pointing to, if you have any suggestions for the future, feel free to let me know!

Read more »

  • Vote: I like it
  • +102
  • Vote: I do not like it

By SecondThread, history, 4 months ago, In English

Currently on codeforces comments, you can see whether you up/downvoted by looking at the up/down arrows next to the comment rating. If you upvoted the comment, the up arrow will be green, and if you downvoted it, the down arrow will be red.

However, for blog posts, the only way to tell is to try to vote a second time and see if an error toast appears at the bottom of your screen. A side effect of this is that you can’t ever undo a vote for a blog post or change it from a downvote to an upvote, for instance, even though you can do these things for comments.

Is there any reason for this behavior? It seems to me like being able to see what you voted for and change your vote if you like is much better than the blog post system. If there isn’t any reason for it, would it be difficult to change the blog system to match the comment system?

Read more »

  • Vote: I like it
  • +97
  • Vote: I do not like it

By SecondThread, history, 4 months ago, In English

Please Stop Guaranteeing Things

There are two common meanings for something being “guaranteed”, and often it is up to the reader to guess the author’s intended meaning. This is annoying and creates unnecessary barriers to entry.

Meaning #1: The thing we are guaranteeing is provably true for the given input. The thing we are guaranteeing is simply true. We don’t want to provide a proof since it would be long, unnecessary, and annoying to read, and might spoil the solution, but you have our word that an answer always exists.

Example: We give you two positive integers A and B (1 <= A, B <= 100). Find some positive integer C (1 <= C <= 200) such that C < A + B. It is guaranteed that some C exists.

Meaning #2: The only input that is legal is input for which this is true. The thing we are guaranteeing might not always be true without this guarantee. Thankfully, we are providing this guarantee so that you only need to concern yourself with solving the problem for inputs in which this is true.

Example: We give you two integers A and B (1<=A, B <= 100). Find some integer C such that (A-C) * (B-C) is negative. It is guaranteed that some C exists.

Examples in real problems:

Examples where 'guarenteed' means that “It can be proven that for all inputs following the constraints, X”

Code Jam 2020 Round 1A, problem B

Codeforces round 642F

Codeforces round 633 Div1B (it's clear what the author meant, but still this type of usage)

Codeforces round 628A

Examples meaning “The only inputs that are valid inputs are inputs for which X”:

Code Jam 2020 Round 2, problem B (An incorrect interpretation of this could have resulted in failing the large test set)

Codeforces round 636A

There are tons of guarantees in the input section for things like: all edges are distinct, the graph is a tree, the array is a permutation, the sum of array sizes across all test cases is reasonable, the total number of queries is reasonable, the input is sorted, et cetera. I didn’t include them because it is clear what they mean. The important part is that this is a completely different type of ‘guarantee’ from the first one. We shouldn't be making contestants figure out what the author means; people want to solve interesting problems, not read novels.


Meaning 1: Make it clear that the ‘guarantee’ is just to make the problem more understandable, not an additional constraint on input.

  • “It can be proven that X”/“Under the given constraints, X is always true”

  • “Notice that some X always exists”.

  • In the example above: “It can be shown that some C always exists.”

Meaning 2: Make it clear that this ‘guarantee’ is an additional constraint on the input.

  • Input is only allowed if X.

  • In the example above: “Only input for which some C exists is legal input.”

Just don’t provide the ‘guarantee’ at all and make it a red herring

  • “If no solution exists, print -1”

  • In the examples above: “If there is no suitable integer C in the valid range, print ‘no’ instead”

Counter Arguments:

"Red herrings don’t work. 99% of the time if there isn’t an impossible case in samples, and the impossible case isn’t super obvious like n=1, then an impossible case just doesn’t exist.”

That’s probably true. One option is to have really weak samples to disguise that, but maybe that is undesirable for other reasons. A second option is to write more problems where there is a nontrivial impossible case, but not put it in samples so people stop thinking this way (definitely keep it in pretests though!). Even without either of these things, there are still some quite nice problems with red herrings for which the contestant proving that it is always possible is helpful. Perhaps you can make the guess that it is always possible and have a slight advantage, but finding why it is always possible is usually a nice head start on the problem too. 2019 China Collegiate Programming Contest Final Problem I is a great example of this. A red herring doesn’t have to trip people up to ‘work’ either; if it makes it clear that it is your job to figure out whether something might happen, that’s okay too.

"You just suck at reading problems. Use samples. Reread the statement. This is a skill, you have to improve it.”

Okay, Um_nik, you got me.

Update: Examples of how to do it the right way:

Problem G from Educational Round 89 is a model solution to this issue. It does an fantastic job of entirely avoiding all ambiguity and confusing guarantees. It is crystal clear that the additional constraint is an additional constraint, and it is worded in a succinct, easy to interpret way. Problem authors/coordinators orz

(My reaction to first reading this problem at 54:13 is pretty funny and might cheer you up if you wrote the problem)

Read more »

  • Vote: I like it
  • +608
  • Vote: I do not like it

By SecondThread, history, 5 months ago, In English

LGM Sniper

I just created a cool CF tool called LGM Sniper. It looks at scoreboard data from every Div1 and Div1+Div2 round ever and tells you which LGM's you have beaten, how many times you have beaten them, and which rounds you beat them in. You can also compare yourself to your friends to see which one of you wins more! If you want to compare yourself with some friends, check the 'show ex-lgms' box and enter the friend you want to compare to as Handle #2, and they will show up on the bottom.

You can try it out for yourself at, or in the competative programming section of Wumbo Games, if you would prefer. Tooltips show the name of the rounds you won in (hover your mouse over the checkmark).

If you find any interesting facts or have suggestions for how I could improve the tool, let me know in the comments!

Don't try to DDOS Codeforces Disclaimer

All data is stored locally on my server. So although these queries are computationally expensive you can't DDOS Codeforces to make a round unrated using this tool because it doesn't actually query Codeforces except for when I update the data, which I obviously won't do during a round. Please don't try to abuse it, you'll just make LGM Sniper slower for other people who might want to get inspired by learning that the beat an LGM and you'll annoy me.

Update: New Features

I added a couple new features/fixes that people brought to me. Here are the ones people will likely care about most:

  • I added a checkbox to only show rounds that were rated in which you beat someone who was an LGM at the time you beat them. If it is checked and you still beat someone, then you definitely earned it!
  • There are now round id numbers shown on the rounds that you won. This is helpful if you want to check out the scoreboard of some contest for instance.
  • I updated the blacklist of excluded contests to not include practice rounds, so it should be more accurate now.

Let me know what you think!

Last Updated:

Includes data from competitions up to and including Round 666 Div1/Div2.

Read more »

  • Vote: I like it
  • +508
  • Vote: I do not like it

By SecondThread, history, 6 months ago, In English

I'm somewhat familiar with how Link Cut Trees work. I have watched Erik Demaine's lecture on them from MIT Open Courseware, solved a couple problems that use them with my team's (very copy-pasteable) book code, and read about them a bit, so I have an idea of how they work in general.

The code I have used supports range path update, path query, link, cut, and checkConnected queries. I read on Wikipedia that Euler Tour Trees are better for subtree queries and link cut trees are better for path queries. However, I looked through ko_osaga's code for fully dynamic connectivity and it looks like he is using a splay tree or link-cut tree of some sort. Link-cut trees use splay trees to store preferred paths, so the size of a splay tree node's subtree doesn't really mean anything, right? But for the dynamic connectivity problem he was trying to solve, I'm pretty sure you need to check, after cutting an edge, which of the trees you created is smaller. That sure doesn't seem like a path operation to me.

So is it possible to do subtree-like operations on LCT's?

Read more »

  • Vote: I like it
  • +13
  • Vote: I do not like it

By SecondThread, history, 10 months ago, In English

According to Wikipedia, an RMQ can be built with $$$O(n)$$$ memory and time precomp that can answer queries in $$$O(1)$$$. The idea is to divide the array into $$$log(n)/4$$$ blocks and then build an RMQ/sparse table normally on each of the blocks using $$$O(nBlocks*log(nBlocks))$$$ time and memory. In this case, $$$nBlocks$$$ is roughly $$$n/log(n)$$$ so the memory and time used to precomp everything is linear. By doing this, we can find the min of all completely covered blocks. That part sounds easy.

The hard part is dealing with the blocks that a query starts and ends in. Wikipedia says that I need to map each block to its corresponding Cartesian tree, and then I can precompute all the answers for every Cartesian tree. I see how, if I could do that, it would be easy to answer queries in $$$O(1)$$$. As I understand it, I could just store which index for a given Cartesian tree contains the relevant min for all pairs of queries within that subarray in $$$O(blockSize^2 * nCartesianTrees)$$$.

But how do I go about quickly (and hopefully cleanly) mapping a subarray to its corresponding Cartesian tree?

Side question: Are there even performance gains to be made here, or am I just wasting my time trying to get rid of this log factor?

Read more »

  • Vote: I like it
  • +43
  • Vote: I do not like it