Flamire's blog

By Flamire, history, 10 months ago, In English

2166A — Same Difference

idea & solution: le0n

Tutorial
Solution

2166B — Tab Closing

idea & solution: le0n

The problem statement arised naturally from closing tabs in any modern browser.

Tutorial
Solution

2165A — Cyclic Merging

idea & solution: le0n

Tutorial
Solution
Solution (linked lists, by Arpa)

2165B — Marble Council

idea & solution: Flamire

Tutorial
Solution (By ZhouYuHang)

2165C — Binary Wine

idea & solution: le0n

Some participants mentioned that similar ideas have appeared recently. We knew of at least one such problem, however, the problem was already proposed and accepted at that time.

I believe that the problems are not identical, though similar ideas were used, it is also a show of skill to remember and reuse ideas learnt from previous problems. Therefore, I would like to think the problem does have a place in the contest.

There was an oversight on the preparation of this problem, the tests did not include enough small tests, which allowed some codes with wrong implementation to pass. We apologize for the inconvenience.

Tutorial
Solution

2165D — Path Split

idea & solution: le0n

Some participants mentioned that similar ideas have appeared recently, we did not know of this.

This problem was initially proposed with a Hall-dp solution, also with complexity $$$O(n)$$$, but testers told us of a simpler greedy solution.

Hint 1
Hint 2
Tutorial
Tutorial (Hall-dp)
Solution
Solution (Hall-dp)

2165E — Rainbow Branch

idea & solution: Flamire

Our testers had vastly different opinions on the difficulty on this problems, some were able to solve within 20mins, and others failed to solve within a sufficiently long time. We eventually decided to put it at E, and it seems to have did its work.

Hint 1
Hint 2
Hint 3
Hint 4
Tutorial
Solution

2165F — Arctic Acquisition

idea & solution: Flamire

No, we did not propose a paper problem. We knew of the paper on permutation pattern matching in advance, but we assumed the paper would not help much in solving the problem, either due to coding complexity, or constants hidden by the notation that would make it impractical. I'll admit that I did not read the paper in full (procrastination), but from what I gathered, it seemed that understanding the paper would be harder than solving the problem in itself.

If I am mistaken, please let me know.

Hint 1
Hint 2
Hint 3
Hint 4
Tutorial
Solution
  • Vote: I like it
  • +203
  • Vote: I do not like it

»
10 months ago, hide # |
Rev. 3  
Vote: I like it -89 Vote: I do not like it

first.

By the way, I was sure that there was some sort of pattern in the problem names, but I could not figure it out. Maybe there is, if there is I just don't see it. But I do think that the name of C. Binary Wine does not fit in with the other names.

First of all, all of the names except for Binary Wine and Arctic Acquisition afaik stand for common competitive programming things when said forward or in reverse.

Same Difference = Data Structures

Tab Closing = Time Complexity

Cyclic Merging = Candidate Master

Marble Council = ^

Binary Wine = ???

Path Split = Shortest Path

Rainbow Branch = Regular Bracket (sequence)

Arctic Acquisition = Alcoholics Anonymous..?

So from here it looks like Arctic Acquisition and Binary Wine don't belong. However, we can insert the common beginning vowel in Arctic Acquisition into the middle of the acronyms of the other titles (and possibly reverse the result to get these):

SAD, CAT, CAM, MAC, SAP, BAR

but then for Binary Wine neither BAW or WAB is a word.

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

D2C/D1A,

"We expected participants to pass using doubly linked list, ..."

But the solution didn't use doubly linked list.
Another day of linked list being forgotten.
It's over meme

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

I think D2E is easier than D2D,it's solution more natually. And I used doubly linked lists in D2C,it's obviously harder to code.The official solution is better

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

    harder to code but coming up with that fancy logic is tougher than implementing a double linked list if you have some practice before of DLL.

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

top 3 reasons for depression

  1. breakup

  2. Substance Abuse

  3. WA in div2 A

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

what is Hall-dp solution in Div1 — D ? Flamire

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

Guys, i think there is error in solution to problem B(Closing tabs). Why there can't answer be greater than 2? Take a look at test case 6, i think for this, we will have to move the cursor 6 times. Kindly take a look at it.

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

    We can prove that the only positions that we need to click are the end position a and the max size of tab b.

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

    yeah , i hope someone could provide a mathmatical proof on why it couldnt be greater than 2 ;

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

      Suppose there are initially x tabs, each with width n / x. Your mouse is currently on the close button of the last tab.

      After closing one tab, the number of tabs becomes x − 1, and each tab gets new width n / (x − 1).

      Now consider two cases:

      Case 1: n / (x − 1) > b

      tab's size is b now !

      ⟹ you must move the mouse to the new location of the first tab’s close button.

      Case 2: n / (x − 1) ≤ b

      Then tab's size will be n / (x − 1)

      Your previous cursor position was at the right edge of the last tab:

      old_pos = (n / x) * x (we have x tab with n/x len)

      new_pos = (n / (x-1)) * (x — 1) (we have x-1 tab with n/(x-1) len)

      So the close button ends up exactly at the same position as before. ⟹ No need to move the mouse.

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

      there are 2 exclsuive situations and they spends of 2/1 moves, therefore we are guaranteed to have the problem solved in at most 2 moves: 1. the total length of tabs greater than window size e.g:

      b|b|b|b|b|b # < move your curor here and close tabs
      wwwwwwwwwww
      

      then you'll have to move the cursor to the right most tab and close tabs until it reachs situation 2.

      1. the total length of tabs less or equal than window size:
       #v move your cursor here and close all tabs.
      bbb|bbb
      wwwwwwwwwwww
      

      hope that gives you some intuition

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

    If you think so

    You may even try on chrome tabs itself !!

    It's always <= 2 for sure !!

    My soln :: https://codeforces.me/contest/2166/submission/359960116

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

Shouldn't the last line of the tutorial of Div2D/1B be max cnt <= \sum_{i \in S} cnt_i ?

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

could you add abit more context to hall-dp mentioned in problem D's editorial ?

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

Could you link the editorial to the contest?

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

I'm a bit disappointed with the editorial, especially after waiting for 24 hours.

For 2165A — Cyclic Merging, it would have been interesting to see:

  • the expected double-linked list implementation
  • a proof of the mathematical formula

rather than the straightforward implementation of the formula, which doesn't bring any added value.

I think an explanation could be the following: consider a graph of $$$n$$$ edges of weight $$$w_i = \max(a_i, a_{(i+1)\bmod n}),$$$ connecting vertices $$$a_i$$$ and $$$a_{(i+1)\bmod n}$$$. You want to build a minimum spanning tree over it. Using Kruskal's algorithm, you pick $$$n-1$$$ edges: all except one having weight $$$\max_i w_i$$$. Therefore, the total weight is $$${\sum_{i=1}^n w_i} - \max_i w_i$$$.

You could think that this problem is not equivalent to the original one, because after picking an edge $$$(a_i, a_{i+1})$$$ (aka merging $$$a_i$$$ and $$$a_{i+1}$$$), $$$w_{i-1}$$$ or $$$w_{i+1}$$$ might increase to $$$w_i$$$, if $$$w_i \gt w_{i-1}$$$ or $$$w_i \gt w_{i+1}$$$, but Kruskal picks edges ordered by weight, so this is not possible (i.e. you are guaranteed that $$$w_{i-1} \ge w_{i}$$$ or that $$$w_{i-1}$$$ was already picked, same for $$$w_{i+1}$$$, therefore at every step the weights remain unchanged).

I feel there’s a nicer explanation, but I'm unable to find it; if you have one, I’d really appreciate if you could share it.

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

    Thanks for your feedback, I have added my proof of the formula, which I hope will be understandable. I have also sourced a greedy implementation from the testers, please check it out.

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

Here's how I did div2C. I started off with the same idea as the editorial, greedily merge the two adjacent elements with the smallest max. However, I couldn't think of a nice way to implement this, so I tried to make some more observations.

Assume we have a set which stores the max of every pair of adjacent elements, and observe how it changes after we merge the elements with the smallest max.

Let these elements be $$$a,b$$$, WLOG $$$a \leq b$$$. Let the element adjacent to $$$a$$$ (and is not $$$b$$$) be $$$x$$$, and let the element adjacent to $$$b$$$ similarly be $$$y$$$. If we merge $$$(a,b)$$$ to $$$b$$$, the only max of our set which could change is $$$\max(x,a)$$$ to $$$\max(x,b)$$$. But since $$$b$$$ was the smallest max, $$$max(x,a) \geq max(a,b)$$$. Taking cases whether $$$a = b$$$ or not, we get either $$$a = b$$$ or $$$x \geq b$$$, and in both cases the element of our set doesn't change.

So our answer is just the $$$n-1$$$ smallest elements of the original set. The largest element of the set is just the max of the array, so just subtract that from the sum of the set. This solves it in $$$O(n)$$$, and doesn't really involve any extra knowledge like cartesian trees.

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

    Thanks for this, it is a very nice way of proving their mathematical formula, you helped me solve it :)

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

Comment canceled because of downvotes.

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

In the div2C instead of checking for smallest element, what if we check for the neighbours of max element. Those can only pair with the other guy (not the maximum). So answer should be the sum of max of all pairs to the left of max cyclically. But could anyone proof that this is always true? For me it passed all the test cases...

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

I had misinterpreted DIV1 — D as we can also rearrange the elements within subsequence. In other words, we have to partition elements into subsets and each subset's elements can be rearranged in a sequence and they satisfy the required property. Is this version solvable ?

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

amazing

»
9 months ago, hide # |
 
Vote: I like it -15 Vote: I do not like it

Why did you provide such a hard tutorial to the D1D (Hall-dp) when it's just greedy?

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

    Any reason why undervoting me?

    P. S. When I wrote this comment there was no "disclaimer" saying anything about greedy.

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

Can you provide some good resources about minimum path cover and how to translate it to bipartite matching? The Wikipedia article is not very illuminating.

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

    Ok I've spent a while looking into this now, and idk how helpful it will be but here's the way I understand it.

    A path cover is just any set of (directed) edges, such that each vertex has at most one incoming and one outgoing edge in the set.*

    The minimal path cover corresponds to the set with the most edges, since the number of paths in that cover is $$$V-E$$$.

    If we create two copies of the vertices, one copy on the 'left' and one on the 'right,' then we'll start drawing edges between them, and let's say that an (undirected) edge from left to right represents outgoing from the vertex represented on the left and incoming into the one on the right. What's cool is that our constraint "at most one incoming and one outgoing per vertex" now translates into "at most one (undirected) edge per vertex in this new copy graph." One vertex copy represents the incoming edge and the other represents the outgoing one. And this is EXACTLY the condition of a bipartite matching.

    So if we build a bipartite matching on the new graph (which in this round's problem the graph is created implicitly), it represents a path cover (at most one incoming and outgoing edge per vertex in the original graph), with the same number of edges (we sort of just 'glue' the left and right halves back together or superimpose them or whatever)! And if we build the MAXIMAL bipartite matching, then this will be the minimum path cover (since it has the most edges).

    The solution for 2165D in the editorial does this matching in two passes, first finding the outgoing edges from odd vertices to even ones (effectively only odd on the left and even on the right, basically ignoring all implicit evens on the left half), then finding all the outgoing edges from evens on the left incoming into odds on the right. These two matchings can be composed using simple addition since the Even->Odd graphs and Odd->Even graphs don't interfere with each other.


    * I think this reframing of the problem was the key to me finally getting that Eureka moment

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

Can someone pls explain Div2D? How to approach writing DP for it? The solution does not seem to be very intuitive.

Any intuition/thought process behind it will be much appreciated

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

@Flamir please explain your DIV2D , knapsack DP more.

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

Can someone explain where and why this is failing ....

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const ll P = 998244353;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T;
    cin >> T;
    while (T--) {
        ll n;
        cin >> n;

        vector<ll> arr(n);
        map<ll, ll> mpp;
        for (auto &it : arr) {
            cin >> it;
            mpp[it]++;
        }

        vector<ll> cnt;
        for (auto &it : mpp) cnt.push_back(it.second);
        sort(cnt.begin(), cnt.end());

        int k = cnt.size();
        vector<vector<ll>> dp(k, vector<ll>(n + 1, 0));

        for (int i = 0; i < k; i++) dp[i][0] = 1;
        
        for(int i=0;i<=cnt[0];i++) dp[0][i] = 1;

        for (int i = 1; i < k; i++) {
            for (int j = 1; j <= n; j++) {
                dp[i][j] = dp[i - 1][j];
            }
            for (int j = cnt[i]; j <= n; j++) {
                dp[i][j] = (dp[i][j] + cnt[i] * dp[i - 1][j - cnt[i]]) % P;
            }
        }

        ll ans = 0;
        for (auto &it : dp[k - 1]) {
            ans = (ans + it) % P;
        }

        cout << (ans-1) << '\n';
    }

    return 0;
}

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

Simpler solution for Div1A/Div2C

Code

Main thing is the maximum element will be selected in last so we can put it in front then we dont need to think about the array being cyclic then merge adjacent elements greedily

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

tuff iota abuse in c 381187850