But Um_nik, we all know how to read, we have our whooping 2 month of experience! Oh, my sweet summer child, my experiments show that many people with kinda cool achievements like medals on ROI don't know how to read statements. But don't worry, I'll teach you. Well, probably you won't understand anything, because you didn't try to understand anything in your life, you expect all hard work to be done for you by someone else. Let's start!
- The result of reading the statement is usually pure math model. If story helps to build correct understanding, you can keep it, but still try to discard as many unnecessary details as possible.
- Imagine you want to tell the problem to someone else. What parts you want to tell? (According to my PM, this rule won't help you).
- Shorter = better.
- Simpler = better.
- Limitations are part of problem statement. Especially small limitations, because for small data you can try all the possibilities.
- Samples are part of problem statement. After building math model, check that you model working correct on samples, at least on small samples where you can check everything fast.
- Notes are part of problem statement.
- Try to find familiar patterns, maybe objects you already know something about. If you are given some connected graph with exactly one simple path between each pair of vertices, it's called tree. 4 letters instead of 12 words, see?
- Try even harder to spot something strange, something you not expecting. That probably will be the cornerstone of the problem.
- If there is some part of the statement you don't like, try to change that to something you like. Start with understanding the object, then simplify it. There are some problems which can be completely solved by this technique.
- If the model you get is very big, try to split it into some pieces. It would be great if pieces are independent, like 'solve problem1, then use its answer as input to problem2 and so on'.
- On first stages it can be useful to write your new statement. On paper. By hand.
- Problemsetters do not write random things in statements. But why would you believe me, since I'm a bad problemsetter? I don't know, maybe you shouldn't.
I'll use Timus for almost all examples. If you see statement in Russian and you don't want to, there is a language switch in upper-left corner.
Assumed workflow: read the statement on Timus, try to understand and simplify it using the rules above. You don't have to read "solution" parts, but I warn you that my concept of reading statements works. I mean, "statement" parts will often contain huge hints to solution.
In most cases I won't write step-by-step explanations how I get the final version. You can say that that's not how teaching works. I can say that you don't want to study. I'll win, because that's my blog.
Given undirected graph, find its spanning tree with minimal diameter.
Diameter has exactly one center. Let's fix the center, it's either vertex or middle of edge. For fixed center the tree with minimal diameter is a tree with minimal height if it's rooted at center. Run BFS to find it.
Given a tree, each vertex has some subset of universe of size m. Find such a path that disjoint union of subsets of vertices on this path is universe.
Something with hashes and mergeable sets. It's not cool, so I won't spend time.
Given an undirected graph with at most 14 (small=important) vertices. Build a bipartite graph: left part is vertices, right part — all simple cycles. Find the minimal number of matchings to cover all the edges.
After that reduction it is kinda known problem, you will also need some subset DP (see? small=important) to calculate needed values.
Count the number of complete subgraphs. Nice and easy. Oh, doesn't work on samples? Yeah, +1, because it's the first day they won't find new complete subgraph. Whatever.
Calculate number of m ≤ n such that gcd(a2 + m2, 4(a + m)) ≠ 1. Wow, it is not geometry, it is number theory problem?! Who would know! Except, like, anyone who read the problem statement.
Now I'll try to explain something.
Wait what? Sum of distances? Circular strings? Sounds hard. But actually this problem is much easier for circular strings. Let's try to change sum of distances to something nicer. We compare some pairs of characters and add 1 to sum if they're different. What pairs? Well... all pairs. All pairs exactly once.
We have some strings with blanks, and we want to fill blanks such that number of pairs of different characters is minimal.
We kinda already did solve. It is obvious that if we have blanks only in one string, we should fill all of them with most frequent character in the other string. Applying this to any solution we get that in each string all blanks are filled with same characters. If they are different for two strings, they should be chosen independently and be the most frequent character in the other string except blanks. If they are equal. we can try all the possibilities.
This looks terrifying. Let's start unravelling. What are our possible actions? Add one plate on top or remove topmost plate. Sooo, first in last out. That looks like stack. That's exactly stack.
That's a good start. So we have a stack and n types of things we can put in stack. But there are also some timetables which describes our actions. And we should count the number of this timetables...
What if we look at it from the other side? We have a timetable and use a stack to model actions described by a timetable. Don't we have something similar that we already know?
Here you need some experience and some magic, but sooner or later you'll understand that timetable is correct brackets sequence with n different bracket types.
OK. Now the problem operates with some familiar objects. We have to count the number of correct brackets sequence of given length, and there is also some conditions on what brackets can be opened at any given time. And the number of bracket types is not greater than 10 which kinda presumes using mask as a DP state.
We are only interested in weekdays, so basically we are living modulo 7. 7 is prime, that gives us hope. Each sort of honey takes some fixed but unknown number of days to eat. Let's call them xi. And we have some information about... linear combinations of xi? In form of equations modulo 7 i.e. in the field? Cool, it is a problem about gaussian elimination. And number of queries is convenient! Going through statement once more confirms: all we have to do is maintain basis of some system of linear equations and check if new equations already can be expressed as linear combinations of old, this also handles the consistency part.
We didn't do anything besides reading the statement and we solved a problem with difficulty way beyond 2k.
Given square matrix of size n ≤ 100. Check if there exists a vector with some non-integer coordinates which after multiplying with the matrix becomes all-integer.
WHAAAT. Did you even read the statement, Um_nik? There is something about rings, and rotation, and magic, and... WHAAAT. This is certainly some magical geometry, not linear algebra.
Go and read it again. And again.
Now we can talk. Let's denote the number of full rotations of i-th accessible ring by xi. It can be negative, it can be non-integer. Let's denote the number of full rotations of i-th protected ring by yi. (maybe Aji, it is not really important). Yes, that's multiplication of matrix by vector. And yes, we want x to be non-integer and y to be integer. Now go and read the statement again.
Let's assume that if the solution exists then exists the solution with rational x. It can look suspicious, but after some thinking you understand that irrational summands should somehow balance themself out, because we want rational values in the end. I don't remember the proof :)
Let's say that common denominator of all fractions in x is Q. Then is we multiply x by Q, two things will happen: x will become integer but not all coordinates are divisible by Q; y has all coordinates divisible by Q. Or, in other words, we take non-zero vector modulo Q and get zero vector modulo Q. Or matrix rank modulo Q is less than n. Or determinant modulo Q is 0. Well, we should calculate determinant modulo Q, not just take determinant and then take the remainder modulo Q... or should we?
OK. Answer is 'Death' if and only if determinant of given matrix is equal to 1 or - 1. Checking is techincal.
Coolest trick of reading statements
We have a minimal spanning tree on Euclidian plane, we should choose its DFS order to minimize sum of distances between neighboring points. Cool, sounds like we understand the statement, what's next? Not so fast.
Let's deal with small details first. What do we mean by 'choosing DFS order'? Isn't it fixed for tree? Well, no, because we can change the order of sons for every vertex. Distances in objective function measured on plane, not on tree.
We have a minimal spanning tree on Eucl... Wait. We don't have 'a tree', we have a minimal spanning tree. Minimal spanning tree of what? Well, of complete graph on these points. OK, cool, why do we need it? Isn't problem the same for all trees? Looks like it is true. And isn't it true that any tree can be spanning for some graph? For example, let's build a graph in which weight of an edge is a distance on tree between its endpoints. For sure our tree will be MST for this graph. What a stupid person wrote this statement!
Problemsetters. DO NOT. Write. Random things.
Strange things. ARE. Important.
Let's THINK. I know, I know, it is hard, and you already showed that problemsetter is stupid, it is time to write your almighty clarification to show who is boss. But for one second. Let's analyze all the things in this statement.
Yes, it is true that any tree can be MST for some graph. But can any graph be a graph with Euclidian metric? Not really. We should have triangle inequality... and we have it for our example. So problemsetter is still stupid? Not so fast. Euclidian plane is not just a metric, it is some fixed metric. And we have geometry. We can measure angles, for example.
Let's look at our MST. Take some vertex v and two its different neighbors u and w. What do we know? The distance between u and w should be the largest among these three vertices, otherwise it won't be MST. A greater angle of a triangle is opposite a greater side. Yeah, that useless theorem from school geometry. It says that angle between two edges from one vertex is at least π / 3. And strictly greater, if vertices are in integer points. From this we can conclude that degree of any vertex in our MST is not greater than 5.
That can't be true. For sure problemsetter would write this in statement if it was true. It is limitation on input, problemsetters are obliged to write these! Oh really.
Probably there is more that you can extract from MST in Euclidian metric, but the fact about degrees is sufficient to solve a problem.
Different math models will lead you to different solutions
Well, only if you have some patterns of how you should solve problems. And you should have them, patterns are good, they're the fastest way to solve problems.
We have to choose radii for given centers in order to cover a circle with smaller circles. We want to minimize maximum of radii.
Oh, min max problem, I know what to do! Do binary search on answer, then check if circles with given radius cover big circle.
And it is correct solution, but it works in (intersect n2 pairs of circles and check all the intersections in O(n) time). It is geometry, operations are heavy, we can get TL.
Let's think about covering given point of big circle. What small circle will cover it? Of course the closest. So, we are interested in maximal distance between some point inside big circle and closest in given set of points. That's obviously a problem on Voronoi diagram. Now O(n3) is very easy, is standard and is possible, probably only with library code :)
This observation costs medals for some teams on ICPC WF 2018. Our team also stuck with first model and didn't even try to code because implementation seems very heavy and we were sure that it will get TL. To be frank, also no one in our team could write Voronoi in , so it is not that important :)
Eliminating things you don't like can solve the problem
Last example in this blog will be not from Timus, it is 2016 Yandex.Algorithm Round 3, Problem F, shout-out to Endagorion for creating such pearl.
Problems visible only to participants, so I'll give already simplified problem statement here:
Given a tree, all vertices are initially white. Two players, Red and Blue, take turns coloring white vertices (surprise) red and blue. The game ends when there are no white vertices left. The score of the game is CR - CB, where CR is a number of connected components on red vertices, and CB is a number of connected components on blue vertices. Red wants to maximize the score, Blue wants to minimize it. Find the score if both play optimally. n ≤ 2·105.
The statement is clear, but we don't like the formula. Especially we don't like Ci, because they change unpredictably. What can we say about connected components after deleting some vertices of a tree? Well, they are all trees themself. What we know about trees? Number of vertices is exactly 1 bigger than number of edges. OK, so number of components in a forest is exactly number of vertices minus number of edges. We can now rewrite the formula. CR - CB = (VR - ER) - (VB - EB) = EB - ER + (VR - VB). Value in brackets is constant, it is . So now we play not for components, but for edges. Better, but still not obvious.
We control vertices, can we somehow express Ei using only vertices? Do we have any equations expressing number of edges through vertices? Yes, we have. . But for calculating ER we should sum only degR(v), the number of red neighbors. That's bad, but let's try anyways.
. Turns out this is true, because all RB-edges cancel out.
So, formula for score is
Now it is easy to see that each player should take vertex with smallest degree available at the moment.