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

Автор PvPro, история, 16 месяцев назад, перевод, По-русски

Надеюсь, задания всем понравились, и спасибо за участие.

2110A - Модный массив

Разбор
Решение

2110B - Долой скобки

Разбор
Решение

2110C - Гонки

Разбор
Решение

2110D - Меньше батареек

Разбор
Решение

2110E - Мелодия

Разбор
Решение

2110F - Факультет

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

»
16 месяцев назад, скрыть # |
 
Проголосовать: нравится +32 Проголосовать: не нравится
  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 месяцев назад, скрыть # |
 
Проголосовать: нравится +17 Проголосовать: не нравится

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

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

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 месяцев назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

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

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

    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 месяцев назад, скрыть # ^ |
      Rev. 4  
      Проголосовать: нравится 0 Проголосовать: не нравится

      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 месяцев назад, скрыть # ^ |
     
    Проголосовать: нравится +3 Проголосовать: не нравится

    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 месяцев назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится

      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 месяцев назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится

      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 месяцев назад, скрыть # ^ |
     
    Проголосовать: нравится +1 Проголосовать: не нравится

    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 месяцев назад, скрыть # ^ |
    Rev. 2  
    Проголосовать: нравится 0 Проголосовать: не нравится

    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 месяцев назад, скрыть # ^ |
      Rev. 2  
      Проголосовать: нравится 0 Проголосовать: не нравится

      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 месяцев назад, скрыть # ^ |
        Rev. 3  
        Проголосовать: нравится 0 Проголосовать: не нравится

        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 месяцев назад, скрыть # |
 
Проголосовать: нравится +82 Проголосовать: не нравится

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 месяцев назад, скрыть # |
 
Проголосовать: нравится +16 Проголосовать: не нравится

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 месяцев назад, скрыть # |
Rev. 3  
Проголосовать: нравится +9 Проголосовать: не нравится

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 месяцев назад, скрыть # |
Rev. 3  
Проголосовать: нравится 0 Проголосовать: не нравится

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

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

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

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

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 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

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 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

This works too. (For D)

BFS after Sorting by Weights
»
16 месяцев назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится

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 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

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

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

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

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

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

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 месяцев назад, скрыть # |
Rev. 3  
Проголосовать: нравится 0 Проголосовать: не нравится

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 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

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 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

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 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

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 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

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

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

    (()()) 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 месяцев назад, скрыть # |
 
Проголосовать: нравится +12 Проголосовать: не нравится

Here is an enhanced version of the problem F.

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

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

Can anyone give me a test case where this fails?

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

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 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

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 месяцев назад, скрыть # ^ |
    Rev. 2  
    Проголосовать: нравится 0 Проголосовать: не нравится

    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 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

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 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

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 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

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 месяцев назад, скрыть # |
Rev. 2  
Проголосовать: нравится -8 Проголосовать: не нравится

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 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

how strong intuition needed to solve F

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

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

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

F is a really beautiful problem