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

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

First, I really need to apologize for the round. There was a serious problem in D that was even covered in the sample test, that the main solution did not handle correctly. I should have been much more careful with this problem and looked for these kind of cases. Unfortunately, it was a big enough issue that caused the round to be unrated. I know this upset a lot of people, but it's tricky to find a solution to this kind of problem after the problem has happened.

I still hope the problems were good quality. If you learned something new from the round, or from this editorial, then the round was worth it. I would advise to solve the problems you couldn't solve during the contest, so you can take away something from the round.

If you want any further clarification on a problem, please ask in comments!

821A — Okabe and Future Gadget Laboratory

We can simulate exactly what's described in the statement: loop over all cells not equal to 1 and check if it doesn't break the city property. To check if a cell breaks the property, just loop over an element in the same row, and an element in the same column, and see if they can add to give the cell's number. The complexity is O(n4).

Sidenote: The definition of lab here was actually inspired from a USAMTS problem in 2016.

Code

821B — Okabe and Banana Trees

The critical observation to make is that the optimal rectangle should always have a lower-left vertex at the origin. This is due to the fact that the line has positive y-intercept and negative slope: any rectangle which doesn't have a vertex at the origin could easily be extended to have a vertex at the origin and even more bananas.

Then, we just need to try every x-coordinate for the upper-right corner of the box and pick the maximum y-coordinate without going over the line. We can compute the sum of any rectangle in O(1) using arithmetic series sums, so this becomes O(bm) because the x-intercept can be up to bm. You can make it faster by trying every y-coordinate; this makes the complexity O(b), but this was unnecessary to solve the problem.

Can you solve the problem with better complexity?

O(b) Code

821C — Okabe and Boxes

It looks like Daru should only reorder the boxes when he has to (i.e. he gets a remove operation on a number which isn't at the top of the stack). The proof is simple: reordering when Daru has more boxes is always not worse than reordering when he has less boxes, because Daru can sort more boxes into the optimal arrangement. Therefore, our greedy algorithm is as follows: simulate all the steps until we need to reorder, and then we resort the stack in ascending order from top to bottom.

This has complexity O(n2 log n). However, we can speed this up if we note that whenever we reorder boxes, any box currently on the stack can be put in an optimal position and we can pretty much forget about it. So whenever we reorder, we can just clear the stack as well and continue. This gives us O(n) complexity because every element is added and removed exactly once.

Code

821D — Okabe and City

First, let's make this problem into one on a graph. The important piece of information is the row and column we're on, so we'll create a node like this for every lit cell in the grid. Edges in the graph are 0 between 2 nodes if we can reach the other immediately, or 1 if we can light a row/column to get to it. Now it's a shortest path problem: we need to start from a given node, and with minimum distance, reach another node.

Only problem is, number of edges can be large, causing the algorithm to time out. There are a lot of options here to reduce number of transitions. The most elegant one I found is Benq's solution, which I'll describe here. From a given cell, you can visit any adjacent lit cells. In addition, you can visit any lit cell with difference in rows at most 2, and any lit cell with difference in columns at most 2. So from the cell (r,c), you can just loop over all those cells.

The only tricky part is asking whether the current lit row/column should be a part of our BFS state. Since we fill the entire row/col and can then visit anything on that row/col, it doesn't matter where we came from. This means that you can temporarily light each row/column at most once during the entire BFS search.

So complexity is O(n + m + k), with a log factor somewhere for map or priority queue. Interestingly enough, you can remove the priority queue log factor because the BFS is with weights 0 and 1 only, but it performs slower in practice.

You can see the code implementing this approach below.

Benq's code:

Another approach to this problem was using "virtual nodes". Virtual nodes are an easy way to put transitions between related states while keeping number of edges low. In this problem, we can travel to any lit cell if its row differs by <=2, or its column differs by at most 2, but naively adding edges would cause O(k^2) edges.

Instead, for every row, lets make a virtual node. For every lit cell in this row, put an edge between the lit cell and this virtual node with cost 1. We can do something similar for every column.

Now, it's easy to see that the shortest path in this graph suffices. A minor detail is that we should divide the answer by 2 since every skipping of a row or column ends up costing 2 units of cost.

821E — Okabe and El Psy Kongroo

You can get a naive DP solution by computing f(x, y), the number of ways to reach the point (x, y). It's just f(x - 1, y + 1) + f(x - 1, y) + f(x - 1, y - 1), being careful about staying above x axis and under or on any segments.

To speed it up, note that the transitions are independent of x. This is screaming matrix multiplication! First, if you don't know the matrix exponentiation technique for speeding up DP, you should learn it from here.

Now, let's think of the matrix representation. Since the x dimension is the long one and the y dimension is small, lets store a vector of values dp where dpi is the number of ways to get to a y value of i at the current x value. This will be the initial vector for matrix multiplication.

Now, what about the transition matrix? Since our initial vector has length y and we need a matrix to multiply it with to map it to another vector with length y, we need a y by y matrix. Now, if you think about how matrix multiplication works, you come up with an idea like this: put a 1 in the entry (i,j) if from a y value of i we can reach a y value of j (i.e. |i - j| ≤ 1). Don't believe me, multiply some vector times a matrix of this form to see how and why the transition works.

You can then build this matrix quickly and then matrix exponentiate for under every segment and multiply by the initial vector, then make the result as the new initial vector for the next segment. You should make sure to remove values from the vector if the next segment is lower, or add values to the vector if the next segment is higher. This gives complexity O(nh3 log w) where h = 16 and w = k.

Code
Разбор задач Codeforces Round 420 (Div. 2)
  • Проголосовать: нравится
  • +127
  • Проголосовать: не нравится

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

Auto comment: topic has been updated by send_nodes (previous revision, new revision, compare).

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

Can ternary search be applied in B?

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

How to solve D?

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

Can anyone tell why my solution to problem C got TLE? 28030270

I think it's of O(n.log(n))

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

Will this tasks be in gym? And when? The previous one wasn't add and this is bad not only for me

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

C is still unclear to me. "So whenever we reorder, we can just clear the stack as well and continue" — could someone explain this to me?

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

    Anything on the stack can be reordered into the optimal order such that we don't need to spend any more reorders on them. So we can just forget about them and go on.

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

    Whenever you need to reorder (ie, the top of the stack != needed element from 1 to n), you reorder the whole stack and put all elements in their optimal place. After this there are two cases:

    1. The elements you add afterwards are correct in order: In this case it's obvious you are done.

    2. The elements you add afterwards are not correct: In this case, you will encounter another need to sort, and by doing so, you implicitly sort the entire stack that has been cleared before and refine the order, then you can clear the stack again.

    Here is my code

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

http://mirror.codeforces.com/contest/821/submission/28040965 — this is my submission to problem D, WA 14 (48 + 49 later on), differences between my solution and tests are quite big (3 to 6, 4 to 20), can anyone take a look and maybe see what's wrong? Edit: I made a super wrong assumption, AC now.

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

    Can you share your approach for the problem D?

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

      Sure! In a BFS, in each layer (first layer starts from (1,1)) I visit all lit cells I can go to without having to lit any column/row (so those that form a path), and meanwhile I remember all columns and rows I visited during this BFS. When my queue gets empty, I've either:

      1. Visited bottom-right corner, so answer is number of layer I'm on right now.
      2. Visited last column or last row, so answer is number of layer + 1.
      3. Neither of those, so I need to get nodes for my next layer. That's why I collect all columns and rows, because all nodes in a new layer will be close to them. If I visited row x, new nodes can be in row x — 2 (only lit ones), x — 1 (all of them), x + 1, x + 2. Same thing happens with columns. If I have not added any new nodes to my next layer, answer is -1, otherwise proceed with the next layer with number + 1.
»
9 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Why my solution in D fails: Solution

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

Problem B is classical "Largest Rectangle in a Right Triangle" problem. https://www.youtube.com/watch?v=UzftAa_sXYs And I guess the solution with better complexity mentioned by the author implements this idea.

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

    i did same but got wrong answer on testcase 4

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

      In general, if a rectangle goes up to the integer coordinates (x, y) then we must count bananas. Maximizing the area would work if we had that , however, consider a = 10, b = 73, c = 95, d = 7. We have that ab = 730, cd = 665, but f(a, b) = 33781 and f(c, d) = 39168.

      A possible intuition on this would come from observing that the area function is "quadratic" and the banana sum function is "cubic" in terms of amount of variables multiplied together. These functions are very unlikely to grow together in the general case.

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

    The problem with this idea is that the problem is not looking for the rectangle with largest area. Actually, the solution could easily have a smaller area than the rectangle with largest area. For example, the rectangle formed between (0,0) and (1,5) would have more bananas (36) than the rectangle formed between (0,0) and (2,2), (only 18) even though it has less area. You are thinking that each node contributes the same number of bananas, but if you read carefully, you see that it is not true.

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

please help http://mirror.codeforces.com/contest/821/submission/28042958 This is my code for C. As you can see, in test 2 it fails (my output is 1 and ans is 2). BUT, when I run code myself I get correct answer (2) ! c++11 in codeblocks..

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

I know about alternative solution for B with ternary search. It's okay, but I'm confused with the barriers when the search has finished. I think that I should consider only [left — m; right + m] to find the answer, but I have WA because of small range of my selection. So, maybe someone can help me with finding good barriers when the search has finished. My code — http://mirror.codeforces.com/contest/821/submission/28042340

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

Auto comment: topic has been updated by send_nodes (previous revision, new revision, compare).

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

Can D be solved with this approach: For every row and column store minimum cost from (0,0). Then x from 0 to n and y from 0 to m (if it's lit) (x, y)=min( min(row(y-1), row(y-2), col(x-1), col(x-2) min(row(y+1), row(y+2), col(x+1), col(x+2), row(x), col(y))+1,(x-1,y),(x,y-1))

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

    DP doesn't work here because the recurrence might have cycles because we can walk on connected components of lit cells. Usually when the recurrence has cycles, you should immediately look at a BFS or DFS solution like the one in the editorial.

    Note: I'm assuming you mean a DP like approach. If not, that's a totally different issue :)

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

Problem c:

add 1 remove add 2 remove

why he need 1 time to reorder ?Does he need to reorder in this case ?

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

Clearing the stack will take O(n) time in worst case,which makes your algorithm O(n^2) worst case. A better approach will be to store the length of corrected size of stack in a counter variable. Correct me if I am wrong!

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

I can't figure out why the 4th test case answer is 3 and not 4 for problem D. The note says that Okabe pays only when moving to (1, 2), (3, 4), and (5, 4). But what about when he moves to (2,3) or (3,2)? Why does he not have to pay then?

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

How to prove the upper bound of the number of edges in D?

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

I am having difficulty in understanding E, how can we apply matrix exponentiation , someone plz explain in detail , i m naive to these type of questions, what exactly does the matrix exponentiation give ??

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

4B — "There are no trees nor bananas in other points" — what is the purpose of this sentence? Clearly there must be bananas and tress at other points, else the problem doesn't make sense?

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

    The problem states that, for every non-negative integers x and y, there are bananas at the point (x,y). Now, we need to know about all the other points of the plane: are there bananas at points (-1,-1) or (0.1,0.1), for example? This sentence you transcribed tells us that there are not, it is a necessary information for solving the problem.

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

I am quite surprised that problem D has a 4s TL when there exists an O(n+m+k) solution, when I saw the 4s TL and k <= 10^4 constraint I just simply lowered my guard and embraced O(k^2) without optimizing building edge between the lights.

My code with SPFA

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

For the link that you gave for E, https://www.hackerrank.com/topics/matrix-exponentiation, how is the number at (0, 0) the required valued in the exponentiated matrix directly ?, don't we need to do matrix exponentiation and then multiply the resultant matrix with the initial value column vector to get the required value ?

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

For problem D. In addition, you can visit any lit cell with difference in rows at most 2, and any lit cell with difference in columns at most 2 ? Can someone explain why?

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

Please, can you not use define in editorial? It do code more unreadable.

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

Can anyone explain me that why in problem D, the sample data #4 outputs 3?

According to my understanding to this problem, it should be -1

In the sample data explaination, it literally says paying when moving to (1, 2), (3, 4), and (5, 4).

But how could u go to (3,2) without paying 1 coin to light all the cells in col #2?

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

My O(1) solution for the problem B

#include <iostream>
#include <cmath>
#include <algorithm>

typedef long long int64;
using namespace std;

int main()
{
	int64 m, b;
	cin >> m >> b;	
	if (m == 1)
	{
	        int64 x = b / 2;
		int64 y = -x + b;
		cout << ((x+1) * (y+1) * (x + y)) / 2 << endl;
	}
	else
	{
		double A = 3.0 / (m*m) - 3.0 / m; 
		double B = -4.0 * b / m + 2.0 * (b + 1) + 2.0 / (m*m) - 4.0 / m;
		double C = -2.0 * b / m + 1.0 * (b + 2) * b - 1.0 / m + 1.0;
		double D = sqrt(B*B - 4*A*C);
		int64 X = (int64)trunc((-B - D) / (2 * A));
		int64 x1 = X - X % m;
		int64 x2 = x1 + m;
		int64 y1 = -x1 / m + b;
		int64 y2 = -x2 / m + b;
		int64 area1 = ((x1 + 1)*(y1 + 1) *(x1 + y1)) / 2;
		int64 area2 = ((x2 + 1)*(y2 + 1) *(x2 + y2)) / 2;
		cout << max(area1, area2) << endl;
	}

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

in B you need to make solution faster O(b) if you use python. My solution on python O(mb) can not pass.

this makes the complexity O(b), but this was unnecessary to solve the problem.

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

My D solution that works in O(k^2 * log(k)) got MLE in test 28. Then i replaced int with unsigned short and it's AC in less than a second :D 28057357

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

My solution for D is slower than the expected solution, it is O(k^2). I am describing it below since I could not see any comment mentioning the same method.

Make connected components of lit cells and now do a BFS from the component in which (1, 1) belongs. The edges between components in this BFS can be determined by seeing the seeing whether we can join the 2 components by lighting a single row / column.

The memory used is less, i.e O(k) but time complexity is O(k^2).

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

In question E ,How are transitions independent of x ???

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

can anyone explain question e matrix formulation proof

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

I dont understand solution for D. We make nodes only for lit cells?

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

RE: 821B — Okabe and Banana Trees — Challenge: Can you solve the problem with better complexity?

The following is an O(1) algorithm for solving the problem, implemented in GNU C++14.

http://mirror.codeforces.com/contest/821/submission/28066366

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

can someone pls look into my code? it's similar to one in editorial but with few changes. i think the problem is in handling case when lower-right cell is not lit. but i can't figure out what's wrong.

Edit: nvm, there was bug in my code, a stupid bug. here is AC code