awoo's blog

By awoo, history, 2 months ago, translation, In English

1923A - Moving Chips

Idea: BledDest

Tutorial
Solution (BledDest)

1923B - Monsters Attack!

Idea: BledDest

Tutorial
Solution (Neon)

1923C - Find B

Idea: Roms

Tutorial
Solution (Roms)

1923D - Slimes

Idea: BledDest

Tutorial
Solution (Neon)

1923E - Count Paths

Idea: BledDest

Tutorial
Solution (awoo)

1923F - Shrink-Reverse

Idea: adedalic

Tutorial
Solution (adedalic)
  • Vote: I like it
  • +62
  • Vote: I do not like it

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

I think E has same idea as this

»
2 months ago, # |
  Vote: I like it +6 Vote: I do not like it

Problem C video Editorial : YOUTUBE VIDEO LINK Audio : English

  • »
    »
    2 months ago, # ^ |
    Rev. 2   Vote: I like it -35 Vote: I do not like it

    Bro in problem C why we can not only check the no. of ones in subarray, if no. of one is greater than (r-l)/2 than not possible . why my solution fail can you tell me. Pease Don't downvote me.

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

      Test case :

      1

      6 1

      1 1 1 1 4 4

      1 6

      You can choose array b as : 2 2 2 2 2 2

      The main thing is ... You have to place 1 (in array b) on the elements which are not equal to 1 (in array a). and After placing 1, the remaining sum should be distributed among the elements which are 1 in array a. I hope it is clear

      You can refer to the video solution for detailed explanation.

    • »
      »
      »
      2 months ago, # ^ |
        Vote: I like it +13 Vote: I do not like it

      bro sent your code as a spoiler or as a link

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

        Bro why is so dowvnvotes in my question

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

          Because of the way you wrote the code in your comment, the first few lines have a very large font size , and the rest are very small with no ne lines for each statement , it's not readable and it takes up a lot of space.it's a common practice to put your code in a spoiler

»
2 months ago, # |
Rev. 2   Vote: I like it +104 Vote: I do not like it

E can be solved linearly.

edit : I lost some rating but I think the problems were very nice :)

  • »
    »
    2 months ago, # ^ |
      Vote: I like it +7 Vote: I do not like it

    It was very beautiful solution.

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

    Can you explain this solution a bit ,like what is going in the dfs call

    • »
      »
      »
      2 months ago, # ^ |
        Vote: I like it +15 Vote: I do not like it

      At any point in the dfs, we keep track of how many beautiful paths we can create if we encounter every given color (the array stores it). So when we enter a vertex in the dfs, we can increment the beautiful path counter by the value for the color in the array.

      Then, on each subtree we explore from this new call to dfs, we just need to reset the value of the current color to 1, because it will block any path to previously visited vertices of the same color.

      Finally, when leaving the dfs, we should increase the initial value of the current color by one, because there will be one more beautiful path if we encounter the same color again. Try drawing what happens, it helps.

      • »
        »
        »
        »
        2 months ago, # ^ |
          Vote: I like it +6 Vote: I do not like it

        Thank you for the explanation. Indeed a very beautiful solution.

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

    Outstanding solution, thank you for sharing!

  • »
    »
    2 months ago, # ^ |
      Vote: I like it -12 Vote: I do not like it

    Wow, exactly like my solution: 248115690. The human brain is mysterious!

  • »
    »
    5 weeks ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    So elegant!

»
2 months ago, # |
  Vote: I like it +1 Vote: I do not like it

Wow, I just see a solution of E which takes $$$O(n)$$$ time. It just uses 1 DFS to calculate the result synchronously just by how we will do to find out the result of one color.

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

I solved E with centroid decomposition (which is $$$O(n log n)$$$) but got TLE.247977712

But the Editorial says authors were expecting $$$O(n log^2 n)$$$ solutions. I'm confused.

  • »
    »
    2 months ago, # ^ |
      Vote: I like it +5 Vote: I do not like it

    Are you sure it is $$$O(n log n)$$$? It can't pass even if you increase time limit to $$$15$$$ seconds.

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

      I check it again, I think all the things I do in function CD is linear.

      $$$T(n) = 2T(\frac{n}{2})+O(12 n)$$$(worst case of recurrance) implies that my solution has a time complexity of $$$O(n log n)$$$(Master theorem). Maybe I implement something wrong.(Or learnt centroid decomposition or Master theorem in the wrong way?)

      Btw, how did you know my code would TLE even if the time limit was 15 seconds?

      • »
        »
        »
        »
        2 months ago, # ^ |
        Rev. 3   Vote: I like it +1 Vote: I do not like it

        You can create a mashup and increase TL to 15 seconds. I don't know centroid decomposition lol:(

      • »
        »
        »
        »
        2 months ago, # ^ |
          Vote: I like it +7 Vote: I do not like it

        I checked again. It works $$$8$$$ seconds on test where $$$t = 1, n = 20000, a[i] = 1$$$ and graph edges = $$$(1, 2), (2, 3), (3, 4)$$$, .... So i think it's $$$n^2$$$.

        • »
          »
          »
          »
          »
          2 months ago, # ^ |
          Rev. 5   Vote: I like it +11 Vote: I do not like it

          Yes, you are probably right, my solution should be $$$O(n log n)$$$ indeed. However, the way i find centroids is wrong, causing my solution having $$$O(n^2)$$$ complexity. I fixed that and got AC.

          Thanks a lot!

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

Hello Codeforces! Please explain what virtual trees are (they are used in the second solution of the problem E).

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

Need Help.

Why does this solution give tle while the one given in editorial passes for the problem 1923E - Count Paths.

248160733

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

    It's probably because you are merging everything into the parent instead of merging smaller children into the largest child. Merging everything means more merging work, which takes more time.

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

Can someone please tell on which case this is failing?

Spoiler
»
2 months ago, # |
  Vote: I like it 0 Vote: I do not like it

I had an idea that works in O(n):

Check this code:

https://codeforces.com/contest/1923/submission/247999826

»
2 months ago, # |
Rev. 2   Vote: I like it +5 Vote: I do not like it

i have solved E linearly. Here is the solution

here ans[c] means how many visited nodes of color c are available to be the first vertex .

when we are going forward we can only add 1 node of that color with new node. And when we go backward we are getting 1 extra node to add with new nodes.

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

In problem B, why is it always optimal to hit the nearest monster? There can be a possibility that there was another monster far away with much much greater health, and if certain bullets were not provided to them within the starting seconds, they would definitely hit the origin.

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

    If that's the case, then you are doomed, since if you don't kill the closer monster first he will kill you before the further monster reaches you.

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

I would love to know if someone can tell me why my solution to problem C is so slow (2308 ms)

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

    I think it's because you used endl instead of '\n' at the end of outputting a new line. I don't quite know how this works exactly but endl does a operation called "flushing" after it outputs while '\n' doesn't. You might also want to add the following to improve your IO speed (This will only work with \n, endl will still slow your IO speed even if you add this code):

    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    

    Here is my submission with endl and this code (1185 ms): submission

    Here is my submission with '\n' and this code (296 ms): submission

    For further information on how this works read this USACO guide article: Link

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

      Thank you for your comment but I have defined endl as "\n"! Ill' add those 2 lines, thanks!

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

      yes, that's correct i also getting reduced time with 186ms from 982ms but just writing those to lines...

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

The third case in Tutorial-C: If this sum is greater than ...

Change 'greater' to 'smaller'.

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

You can use divide and conquer on tree to solve problem E easily in $$$O(n \log n)$$$ too. It is easy to think.

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

    yeah, just use centroid decomposition. But I use an unordered set and could AC it. How can you do it in Nlogn?

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

If someone want to consult a centroid decomposition + set solution can see my submission: 248033502. My idea: I can count the number of way cross the centroid node for all node and use set to manage the first node in DFS way has color C.

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

I am unable to understand why the solution to problem E has time complexity O(n log^2 n ). For every node, we are iteration through all the children, and then for every child we are iterating through every color it has. Can someone explain it to me?

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

    It's a type of "DSU Merging". When a vertice's color set is iterated, the destination set size must be at least twice of the original one, so the total movement is at most $$$O(\log n)$$$ for each node, then the final movement is at most $$$O(n \log n)$$$. With the complexity of map, the final complexity is $$$O(n \log^2 n)$$$.

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

I think there are some mistakes in tutorial for problem 1923C — Find B

To answer query l , r at first let's try to find the array b with the minimum value of ∑bi . For this, for indexes i , where ci=1 we have to set bi=2 , and for indexes i , where ci>i we have to set bi=1 . Thus, the sum of all elements in array b equal to cnt1⋅2+(r−l+1)−cnt1 or (r−l+1)+cnt1

. Now we have three cases:

If this sum is greater than ∑ri=lci then the answer is NO

If this sum is equal to ∑ri=lci then the answer is YES

If this sum is greater than ∑ri=lci then we can add this excess to the maximal element in array b In this case, the answer is YES

instead of ci>i, shouldn't it be ci>1 ?

In third case, shouldn't it be smaller instead of greater?

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

My solution for C got hacked. It seems somes python solutions are just taking more time. Can somebody explain ?

def f(c,l,r):
  if l == r:
    return False
  return c[r]-c[l-1] >= 0

def solve():
  n,q = list(map(int,input().split()))
  a = list(map(int,input().split()))
  b = [ -1 if x == 1 else x - 1 for x in a]  
  
  c = [0] 
  for i in range(n):
    c.append(c[-1]+b[i])

  for i in range(q): 
    l,r = map(int,input().split())
    if f(c, l, r): 
      print('yes')
    else:
      print('no')

   
t = int(input())
for _ in range(t):
  solve()
»
2 months ago, # |
  Vote: I like it +3 Vote: I do not like it

About F's fact 4, two binary strings should have same number of '1'. Is it true?

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

    If $$$s1=s2$$$, there will be same number of $$$1$$$'s. Otherwise, $$$s1<s2$$$ or $$$s2<s1$$$, and they don't have the same number of $$$1$$$'s. The same relationship will hold between $$$s1'$$$ and $$$s2'$$$ since the fact mentions that we are replacing the same number of $$$0$$$'s with $$$1$$$'s in both strings.

    For this problem though, $$$s1'$$$ and $$$s2'$$$ will always contain the same number of $$$1$$$'s. But this condition is not necessary for $$$s1$$$ and $$$s2$$$.

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

I solved E using stack for each color.

Here is my solution: 248216745

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

Can someone tell me why my solution for B is not working.

My Submission

Approach — stored the sorted vector (distance,hp) in vector p. Then,iterated through vector p and for each monster, calculated the time it would need to be killed by the forumla hp/k. also calculated bullets left in extra. at the start of each iteration , subtracted extra bullets

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

D was a realy good question. Great Contest

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

Explaining Tourist's Solution to D Problem

Objective: For each slime, find min no of operations to eat that slime. One Operation is eating of one slime by an adjacent bigger slime.

Some observations:

  • For each slime, if there is a bigger slime to immediate left/right, then ans for this slime = 1.

Now in other cases

  • If there is a consecutive set of equal-sized slimes, they can't do any operation on each other.

  • Any merging operation to make a bigger slime are made either to the LEFT or RIGHT, not including the index of the slime.

  • Looking at one side (left or right), there must be at least 2 different-sized slimes on this side.

  • Since eventually the adjacent slime needs to get bigger than the current slime, we need to look for the min slimes to include on one side, which has its prefix sum > current slime size, and no of distinct slimes > 1.

  • Since the prefix sum is monotonous for a contiguous range, we can perform binary search on both side to find the min number of slimes to include to satisfy the condition.

  • Explanation of setting limits for binary search: LEFT keep the lo limit at 0, and hi limit at the largest index where slime size is not equal to that of the slime to the immediate left of current slime. Because need to ensure at least 2 different-sized slimes be included in the range.

Pre-processing:

  • l(n) and r(n) : Store the begin and end index of the contiguous equal-sized slime windows.
  • p(n+1) : prefix sum array : its monotonicity property helps use binary search.

Overall Time Complexity: O(nlogn)

  • O(n) time for preprocessing

  • O(nlogn) time for the core implementation: logn time to binary search to LEFT and RIGHT of the current index.

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

248285844 Problem D Whats wrong with my code please someone help. I just don't get why am i getting wrong answer.

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

    Try checking the ok condition before starting the binary search. Sorry , you have already done it. I juat saw it

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

      I found the mistake. I was using return type 'int' for 'summ', but shouldn't it give integer overflow for this?

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

For Problem E, I came up with this simple solution.

void dfs(int s, int p, vector<int> *adj, map<int,int> &m, ll &ans, vector<int> &a){
    ans += m[a[s]];
    int t = m[a[s]];
    for(int u:adj[s]){
        if(u==p)
            continue;
        m[a[s]]=1;
        dfs(u,s,adj,m,ans,a);
    }
    m[a[s]]=t+1;
}
// not pasting template here, scan -> cin, print -> cout
void solve()
{
    int n;
    scan(n);
    vector<int> a(n);
    vscan(a);
    vector<int> adj[n];
    for(int i=0; i<n-1; i++){
        int x,y;
        cin>>x>>y;
        adj[x-1].push_back(y-1);
        adj[y-1].push_back(x-1);
    }
    map<int,int> m;
    ll ans = 0;
    dfs(0,-1,adj,m,ans,a);
    print(ans);
    return;
}
  • »
    »
    2 months ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    Nice solution, you can replace your map with an array for a better complexity.

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

    Would you like to explain ?

    • »
      »
      »
      7 weeks ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      Whenever you visit a node s, a[s] is the value of that node. m[a[s]] will take count of how many nodes have value a[s] before this node with which we can make pair, I mean no other a[s] comes in a way.

      Suppose you visit s, than for a node lying in its subtree there is no other way to make pair instead of s, because s comes in between any other s. So making m[a[s]]=1

      While coming out of the highest level s increasing the number of s by 1 for next s.

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

can we solve C using sparse table ?

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

Can anybody tell , for problem 2 why this code is giving error on test case 2 , https://codeforces.com/contest/1923/submission/248233287

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

For problem D : Can anyone tell why is this code giving wrong answer??248345962

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

Can someone explain why jiangly's solution to problem E works in O(Nlog^2N). I know it utilizes small to large merging, but why does merging by the size of color sets yield that complexity? When we merge some node's children, set size won't necessarily go up 2x. For example combining sets (1,2,3) and (1,2,3) will give us (1,2,3) again, so the regular proof does not apply here.

Edit: Nvm, I neglected the fact that number of colors is always less or equal than the number of nodes in a subtree. The proof is trivial.

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

How does one come up with solutions like that of problem C? :/

  • »
    »
    4 weeks ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    The goal is to make the elements different from the original, whilst not changing the sum.

    An easy thing to do, is decrement one number and increment another. By doing this, we've changed both the numbers from the original whilst still having the same sum.

    Now obviously, we cannot decrement 1, because the third rule states any number must be > 0. Therefore, we are forced to increment all 1s, and forced to decrement all numbers > 1.

    It's easy to see that this is only possible, if the total of all numbers > 1 is not less than the total of numbers equal to 1.

    We can then, of course answer the range queries using prefix/suffix sum.

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

I do not understand why does my submission not pass the second test case and what am I doing wrong here. Can someone please explain? 248388078

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

I made video editorial for E discussing the DP idea (excluding the small to large trick).

I also made a contest with easy version of problem E and some followup problems. Access it here

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

Thanks

»
2 months ago, # |
Rev. 2   Vote: I like it +6 Vote: I do not like it

Problem F's "Fact 4",You should specify that s'1 and s'2 have the same number of 1s , otherwise your statement is wrong.

s1=1000011 s2=1000100 k-1=2 s'1=1001111 s'2=1000111 s1 < s2 and s'1 > s'2

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

For E with Virtual Trees — I think you can do just an modified Euler walk of the tree first, and then walk on only the nodes of the same color in the order of the Euler walk: it will be eqv. to doing DFS on the Virtual Tree. So should be easy to do DP in each node for all its top-level children with/without being a direct descendent of the parent.

The final complexity should be just O(n), better than the O(n log n) of the tutorial.

The modification of the walk is that you put the node each time you visit it, not only first & last time.

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

can someone give me the testcase where this solution (https://codeforces.com/contest/1923/submission/248724413)

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

In problem D,my code got a "Wrong Answer" on test 2. Can anyone give me a hack? Many thanks.

https://codeforces.com/contest/1923/submission/248850524

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

Problem C : what's the mistake in this code? Please help. https://codeforces.com/contest/1923/submission/249311392

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

Is there a typo for the editorial for problem C? Should it be, "and for indexes $$$i$$$, where $$$c_i > 1$$$" instead of $$$c_i > i$$$? That makes more sense to me.

»
3 days ago, # |
  Vote: I like it 0 Vote: I do not like it

How can we do B using DP?