PvPro's blog

By PvPro, history, 16 months ago, In English

I hope everyone enjoyed the tasks, and thank you for participating.

2110A - Fashionable Array

Editorial
Solution

2110B - Down with Brackets

Editorial
Solution

2110C - Racing

Editorial
Solution

2110D - Fewer Batteries

Editorial
Solution

2110E - Melody

Editorial
Solution

2110F - Faculty

Editorial
Solution
  • Vote: I like it
  • +160
  • Vote: I do not like it

| Write comment?
»
16 months ago, hide # |
 
Vote: I like it +32 Vote: I do not like it
  1. Problem names are in Russian
  2. You put F before E in the editorial.

I don't understand how E was accepted by coordinators since it is so standard to anyone who's ever seen Hierholzer's before.

»
16 months ago, hide # |
 
Vote: I like it +17 Vote: I do not like it

I was not able to debug my code for finding Eulerian path, damn sed lyf :(

»
16 months ago, hide # |
Rev. 2  
Vote: I like it 0 Vote: I do not like it

2110D - Fewer Batteries can be solved without binary search too.

Solution is that ->

First for each index store the minimum batteries that will be required from that point so that one is able to reach the endpoint(nth node). That is done by dijisktra on the graph with opposite edge starting from node n and cost as maximum of all the nodes visited .

After that ,minimising the cost with normal dijisktra on forward graph starting with node 0 and cost as maximum of all the nodes visited.

U can look to my submission 321152832

  • »
    »
    16 months ago, hide # ^ |
     
    Vote: I like it 0 Vote: I do not like it

    I thought of this idea too before I realized that $$$s_i \lt t_i$$$

  • »
    »
    16 months ago, hide # ^ |
    Rev. 2  
    Vote: I like it +4 Vote: I do not like it

    I used topological sort 2 times

    1. Topo sort on reversed graph to find, for each node, minimum batteries needed before reaching the node, inorder to reach Nth node from that node.
    2. Topo sort on normal graph, to find the minimum batteries that can be carried from node 1 to node N using the above precomputed values at each node.
    

    Submission: 321166795

    Complexity: O(2 * N)

    • »
      »
      »
      16 months ago, hide # ^ |
      Rev. 4  
      Vote: I like it 0 Vote: I do not like it

      The second topological sort isn't correct because you assume that in each node v you can have any number of batteries between l[v] and r[v] but this is not correct. Here is an example testcase where the solution fails.

      # g++ -O2 nithish654.cpp -o sol.out
      # ./sol.out
      1
      5 6
      2 8 0 100 0
      1 2 2
      1 3 2
      2 3 10
      3 4 2
      3 5 3
      4 5 100
      3 <-- this is the output of your solution
      

      # g++ -O2 official.cpp -o sol2.out # ./sol2.out 1 5 6 2 8 0 100 0 1 2 2 1 3 2 2 3 10 3 4 2 3 5 3 4 5 100 10 <- this is the correct output

      In the above example the problem is for node 3 you have l[3] = 2 r[3] = 10 and you assume you can reach node 3 with 3 batteries and then walk the (3, 5) edge which has weight 3. However you can reach node 3 with either 2 or 10 batteries and nothing in between.

      Another thing which is interesting is that the two dijkstras solution also fails but with an output of 100, I explained why in one of the other replies.

      Edit: Also, you don't need to manually toposort. [1, 2, ..., n] is a valid toposort of the vertices since for each edge (u, v) is holds that u < v from the problem statement.

  • »
    »
    16 months ago, hide # ^ |
     
    Vote: I like it +3 Vote: I do not like it

    in your code: "if (minos[i] > v[1] + arr[i]) continue;"

    isint that wrong? you cant just prune based off of that. you could have taken some more batteries before reaching the maximum edge in that path right? how are you certain that you can eliminate that path completely for finding minimax?

    • »
      »
      »
      16 months ago, hide # ^ |
       
      Vote: I like it 0 Vote: I do not like it

      This lines assures that if the path i am going in is having current batteries less than the minimum required i shouldn't go to that path i.e doesn't minimise the maximum for that because since it has less batteries and I need minimum minos[i] to be able to reach the end , so I will not be able to reach the nth node with these batteries.

    • »
      »
      »
      16 months ago, hide # ^ |
       
      Vote: I like it 0 Vote: I do not like it

      You are correct, it's indeed wrong. if (w > v[1]) is also wrong for the exact same reason. Here is an example where the solution breaks.

      # g++ -O2 Krishbansal333.cpp -o sol.out
      # ./sol.out                            
      1
      5 6
      2 8 0 100 0
      1 2 2
      1 3 2
      2 3 10
      3 4 2
      3 5 3
      4 5 100
      100 <- this is the output of Krishbansal333's solution
      

      # g++ -O2 official.cpp -o sol2.out # ./sol2.out 1 5 6 2 8 0 100 0 1 2 2 1 3 2 2 3 10 3 4 2 3 5 3 4 5 100 10 <- this is the correct output

      In the above example the problem is that node 3 is first reached with 2 batteries and it's assumed the edge (3, 5) which has weight 3 can not be traversed. However node 3 can also be reached with 10 batteries and this is optimal.

  • »
    »
    16 months ago, hide # ^ |
     
    Vote: I like it +1 Vote: I do not like it

    damn nice i wasnt able to think of the first part cuz of that had to do some fluke binary search solution with dijkstra and now my accepted solution gives mle on 31

  • »
    »
    16 months ago, hide # ^ |
    Rev. 2  
    Vote: I like it 0 Vote: I do not like it

    In the first dijkstra in your submission it seems like you can pop a not fully relaxed vertex from the queue. For example:

              (b, 4)
      100 -> /      \ <- 10
    (a, 100)         (d, 0)
      101 -> \      / <- 5
              (c, 5)
    

    In the above imagine the edges in the transposition graph point to the left and you start your dijkstra from (d, 0).

    q = { (0, d) }
    q = { (0, c), (6, b) }
    q = { (1, a), (6, b) } // here you will pop a from the queue the first time
    q = { (6, b) }
    q = { (0, a) } // here you will pop a from the queue for a second time
    

    Since the vertices you pop from the queue aren't necessarily fully relaxed as is the case with usual dijkstra this should have a higher time complexity.

    Edit: I think the best way to avoid this is to use toposort as nithish654 explained in a reply.

    • »
      »
      »
      16 months ago, hide # ^ |
      Rev. 2  
      Vote: I like it 0 Vote: I do not like it

      Are you saying to keep visited array and all , i know that's how people usually write dijkstra but I prefer my way. As much as I know it only visited each node like maximum 2 times so usually works fine and usually keep a if check to avoid that but it is not necessary to do that.

      • »
        »
        »
        »
        16 months ago, hide # ^ |
        Rev. 3  
        Vote: I like it 0 Vote: I do not like it

        No, your dijkstra seems fine implementation-wise, I am just saying that dijkstra in general wouldn't be efficient for finding the minimum number of batteries needed to reach the final vertex since you can't guarantee that the vertex with the smallest cost in the queue is fully relaxed. In some cases this will lead to rerunning dijkstra on part of the graph multiple times (not just 2 but up to n. The above example I gave can be tweaked so that you add a to the queue O(n) times and then each time you add it you run dijkstra on the subgraph to the left of a) The problem is roughly the same as the problem with running dijkstra on a graph where some of the edges can have negative weights (but there is no negative cycle). Dijkstra can solve that problem but with bad time complexity.

»
16 months ago, hide # |
 
Vote: I like it +82 Vote: I do not like it

Problem F could also be solved in O(N), tho it doesn't matter much. Most things are same, except there is one more observation: - Let's say our current array is a[1] <= a[2] <= a[3]... a[N] - Then, we don't actually need to try f(a[i], a[N]), where a[i] <= a[N-1]/2, since max possible value of f(a[i], a[N]) <= min possible value of f(a[N-1], a[N]). (where a[i] * 2 <= a[N-1])

Thus, if the maximum value gets updated (let's say x is new, y is the old one):

  1. 2*y > x, obviously answer = x.

  2. We check elements in range y/2...y. (We can push everything to a set and just iterate from the back).

Well, one can see that we only process an element with a current maximum only once, thus we can just push everything to a vector and clear after each use: 321161406

»
16 months ago, hide # |
 
Vote: I like it +16 Vote: I do not like it

In question D many solution that were accepted shouldn't have passed system testing cause now that I am trying submit those same solution again they are giving MLE on test case 31 which those solutions were not tested against in the system testing phase!

»
16 months ago, hide # |
Rev. 3  
Vote: I like it +9 Vote: I do not like it

My submission for D seems to be $$$\mathcal{O}(n^2)$$$ but there is no testcase to fail it. 321147941

For each node, I compute a list of intervals to describe all the possible battery counts at that node. Then computing these lists is a straightforward DP.

But for each transition between $$$u$$$ and $$$v$$$, $$$v$$$'s entire list must be checked. This motivates a hack testcase: for the first $$$\frac{n}{2}$$$ nodes, form a chain and attach each node to the middle node as well. Then for the other $$$\frac{n}{2}$$$ nodes, attach them to the middle node. The size of the middle node's list is $$$\frac{n}{2}$$$ now, and computing $$$\frac{n}{2}$$$ more transitions from that will give quadratic runtime. Here's the generator if I wasn't clear:

Generator code

My final solution adds some optimization on top of the original idea, but with some work it can be defeated as well.

Is there a way to improve the worst bound for my approach?

»
16 months ago, hide # |
Rev. 3  
Vote: I like it 0 Vote: I do not like it

Did anyone else get Runtime Error on test case 12 while solving E? How did you solve it?

»
16 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

why can dfs pass D?????? i tried many ways but not dfs till 01:30

»
16 months ago, hide # |
 
Vote: I like it +5 Vote: I do not like it

It's really weird that my solution passed just with a break. It does Dijkstra on $$$(idx,sum)$$$, which should be $$$O((n+m)W\log{n})$$$ in the worst case. Can anyone try to uphack it? 321125700

»
16 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

Can anyone tell me why my solution is failing? It says that the jury found a solution, but I don't still can't see why my solution couldn't find the euler path, even after accounting for the euler cycle.

Problem E, -> Submission

»
16 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

This works too. (For D)

BFS after Sorting by Weights
»
16 months ago, hide # |
 
Vote: I like it +1 Vote: I do not like it

Hey for problem C my idea was at every point where there is -1 to check if the minimum element in the remaining array is smaller than or equal to current height.If yes , set that arr[i] to 0 otherwise 1. THen I later check if the given array is able to pass the array But on test 2 , number 89 this shows wrong.

»
16 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

Can anyone help me out in finding a teat case were my code fails

https://codeforces.me/contest/2110/submission/321134907

  • »
    »
    16 months ago, hide # ^ |
     
    Vote: I like it 0 Vote: I do not like it

    Try this case:

    1 2 -1 1 0 2 1 1

    It should output 0 1

  • »
    »
    16 months ago, hide # ^ |
     
    Vote: I like it 0 Vote: I do not like it

    When you hit -1, you always choose to go up, which means you always fly at the height limit, but once you hit a 1 in this state, the programme will throw an wrong -1. like: 4 -1 -1 -1 1 0 1 0 1 0 1 0 1

»
16 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

Could you help me see why the time complexity is qualified? I used the priorityqueue and visit arrays,problem D:321109278

»
16 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

c&d are too easy, though I was stumbled by c because of an imperceptible mistake, which made my rating down

However, e&f are marvelous! I love them very much

»
16 months ago, hide # |
Rev. 3  
Vote: I like it 0 Vote: I do not like it

Can anyone please help me out with why my code fails in pretest 2. 321158954

I store the minimum (along with its index) of all upper limits among the limits from the end to the particular index, and from the range of current index to maximum index of the minimum upper limit i count the number of compulsory 1s using precomputed num1 array in O(1). So we only assign v[i]=1 when h+(number of compulsory 1s)<mini[i] because if we increase h when h+(number of compulsory 1s) is already >=mini[i], the answer would fail because we already exceeded the upper limit of atleast one obstacle.

My code - ~~~~~

void solve(){

int n;
cin >> n;
v32 d(n), num1(n+1);
vv32 p(n, v32(2)), minn(n, v32(2));
forn(i, n) cin >> d[i];
forn(i, n) cin >> p[i][0] >> p[i][1];
forn(i, n) num1[i+1] = num1[i]+(d[i] == 1);
minn[n-1][0] = p[n-1][1]; minn[n-1][1] = n-1;
rforn(i, n-2){
    minn[i] = minn[i+1];
    if(p[i][1] < minn[i][0]) minn[i][0] = p[i][1], minn[i][1] = i;
}

int curh = 0;
forn(i, n){
    if(d[i] >= 0){
        curh += d[i];
        if(curh < p[i][0] || curh > p[i][1]){
            cout << "-1\n";
            return;
        }
    } else {
        int diff = minn[i][0]-curh, ind = minn[i][1], ct1 = num1[ind]-num1[i];
        // cout << diff << " " << ind << " " << ct1 << ln;
        if(ct1 < diff){
            d[i] = 1;
            curh++;
        } else if(ct1 == diff) d[i] = 0;
        else {
            cout << "-1\n";
            return;
        }
        if(curh < p[i][0] || curh > p[i][1]){
            cout << "-1\n";
            return;
        }
    }
}

print_vec(d);

} ~~~~~

  • »
    »
    16 months ago, hide # ^ |
     
    Vote: I like it 0 Vote: I do not like it

    I could not understand your code or explanation , can you maybe explain a bit further , I can give you a simple rundown of the solution

»
16 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

In problem C i applied a greedy approach where i increase the height where ever it is possible .

firstly i calculated the maximum possible height for each obstacle such that i can reach the end .

then updated my values accordingly . can someone tell where can this greedy approach fail .

My submission — 321105467 ??

  • »
    »
    16 months ago, hide # ^ |
    Rev. 4  
    Vote: I like it +1 Vote: I do not like it

    Consider this test case,

    3
    -1 -1 -1
    0 10
    0 10
    0 1

    Here, if you increase the height in both of the first 2 turns, you'll end up missing the third gate

    • »
      »
      »
      16 months ago, hide # ^ |
       
      Vote: I like it 0 Vote: I do not like it

      What if we first do this: for every ri, we set it to the minimum of all rj where j >= i.

      Then, if we increase the height whenever we can, we will not miss any gate's upper limit, and we will be able to clear the lower limits of all gates.

      This sounds okay but this gives me wrong answer, I am yet to figure out why.

      • »
        »
        »
        »
        16 months ago, hide # ^ |
         
        Vote: I like it 0 Vote: I do not like it

        instead of minimum of all rj you can take minimum of extra 1's that rj can bear and then you can greedily increase height. like this 321309570

»
16 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

I had an alternate solution to B. I essentially cut the first opening bracket (always at first position) and last closing bracket (always at last position) and then checked if it was still balanced. It seemed easier to me that messing with the balanace factor arrays.

def isBalanced(s):
    st = []
    for i in range(len(s)):
        if s[i] == '(':
            st.append(s[i])
        else:
            if st and (st[-1] == '(' and s[i] == ')'):
                st.pop()
            else:
                return False
    return not st
 
for _ in range(int(input())):
    s = input()
    s = s[1:-1]
    #print(s)
    print("NO" if isBalanced(s) else "YES")
»
16 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

My initial idea in D was to binary search on the answer and run dijkstra(for each node, find max number of batteries you can end up with there) but that exceeds TL. But it seems like just bfs works: https://codeforces.me/contest/2110/submission/321128976

though it gets TL verdict after removing this line:

if(dist < d[u]) continue;

Cutting down on parallel entries seems to help a lot, but I don't think it makes up for the cases where each d[u] can be updated a lot of times. Can anyone prove the correctness of this or uphack it?

»
16 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

In B I was just checking for the presence of ")(" , where does this logic fail?

  • »
    »
    16 months ago, hide # ^ |
     
    Vote: I like it 0 Vote: I do not like it

    (()()) would break your code as you have )( in (( )( )) but the output here should be NO as removing any open-close bracket pair still keeps it balanced as the balance array is [1, 2, 1, 2, 1, 0] Which has no 0 except the last element (the logic used in the solution)

»
16 months ago, hide # |
 
Vote: I like it +12 Vote: I do not like it

Here is an enhanced version of the problem F.

»
16 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

Why is this solution incorrect: https://codeforces.me/contest/2110/submission/321230391

Can anyone give me a test case where this fails?

»
16 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

Can someone help me in fixing this? I've no clue why this won't work. I know that there is a simpler reduced version of the dijkstra based off the constraint $$$ u_i \lt v_i $$$ but I wanna know what's wrong here...

Submission

»
16 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

Need help

For Problem C(Racing), my solution says "wrong ans on test case: 2". I couldn't find my mistake. For which case scenario, my solution might not work properly? I am genuinely seeking help, please don't down-vote me.

Here is my submission: https://codeforces.me/contest/2110/submission/321800281

  • »
    »
    16 months ago, hide # ^ |
    Rev. 2  
    Vote: I like it 0 Vote: I do not like it

    Hey, I think you are incrementing height in a not so good way. By the way, your cinn and print macros are cool. Let's consider this test case.

    1

    3

    -1 -1 1

    0 2

    0 2

    0 2

    Here your test performs hi = 1, then 2, but at 3rd step it got stuck as now it had to increase mandatorily. So, it outputs -1 but answer do exist 0 0 1 or 0 1 1 or 1 0 1.

    Hope it helps!

»
16 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

it seems that I found an $$$O(n+m)$$$ dp solution for D?

first, for every node, find how many batteries we need at least to reach node n. second, for every node, find the minimum count of batteries we should use to reach current node, and the maximum count of batteries we can collect before we leave current node. using these info, we can know the final answer.

is it completely correct? my accepted submission

»
16 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

My solution to D that passed (and still passes) is brute force and can reach O(2^sqrt(M)) for a complete graph. 321117884

»
16 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

Anyone knows why this solution for problem B (Down with Brackets) works? I basically check if the entire sequence (i.e., String $$$S$$$) has at least two balanced sequences that are concatenated.

»
16 months ago, hide # |
Rev. 2  
Vote: I like it -8 Vote: I do not like it

PLZ PLZ PLZ explain me where my code is failing in C(RACING) it is giving wrong ans on test 2 in test case 474 https://codeforces.me/contest/2110/submission/322820237 .. my logic is doing all -1 1 and store indexes in stack ( dont store those indexes where doind -1 into 1 is a necessity) and when h > r .. take the indexes of stack and make it 0 .. can u read the code and tell the failure test case please

»
13 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

how strong intuition needed to solve F

»
13 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

F is amazing! I can't see any of these three facts.

»
8 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

F is a really beautiful problem