khba's blog

By khba, 7 months ago, In English

Thanks everybody for participating in the round!

You are free to leave feedback in the comments as well!

What is your feedback about the contest?
Which problem did you like the most?
Which problem did you find least enjoyable?

A. Square?

Author: JahonaliX Preparation: khba

Solution
Code (Python)

B. Your name

Author: khba Preparation: khba

Solution
Code (C++)

C. Isamatdin and His Magic Wand!

Author: Isamatdin Preparation: Isamatdin

Solution
Code (C++)

D. Yet Another Array Problem

Author: Nasa Preparation: Muhammadali__ & Nasa

Hint 1
Hint 2
Hint 3
Solution
Code (C++)

E. khba Loves to Sleep!

Author: Isamatdin Preparation: Isamatdin

Solution
Code (C++)

F. Tree, TREE!!!

Author: Nasa Preparation: Nasa

Hint 1
Hint 2
Hint 3
Solution
Code (C++)
Bonus
Hint for bonus 1
Solution for bonus
Code (C++) for bonus

G. Mukhammadali and the Smooth Array

Author: Muhammadali__ Preparation: Muhammadali__

Hint 1
Hint 2
Solution
Code (C++)
Bonus
  • Vote: I like it
  • +93
  • Vote: I do not like it

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

Why did not you set $$$n \leq 2*10^5$$$ for task G?

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

    Solution is quadratic.

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

      which is easy to make $$$O(n\log n)$$$

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

        How?

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

          with a data structure like segment tree, I think.

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

          It is just a LNDS problem.

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

          You want to calculate $$$dp_i[a]$$$, the maximal cost of an increasing subsequence among the first $$$i$$$ values ending at value $$$a$$$. There are at most $$$i$$$ interesting values of $$$a$$$ (the first $$$i$$$ elements of the array), and furthermore, if $$$dp_i[b] \lt dp_i[a]$$$ for some $$$b \gt a$$$, then $$$dp_i[b]$$$ is useless, since you're better off taking the subsequence ending at $$$a$$$. So you're keeping at most $$$i$$$ values of $$$a$$$, and $$$dp_i$$$ is increasing. Therefore, a good way to store $$$dp$$$ is a sorted list of pairs $$$(a, dp_i[a])$$$.

          When going from $$$i - 1$$$ to $$$i$$$, we must add $$$dp_i[v[i]] = dp_{i - 1}[a] + c[i]$$$, where $$$a$$$ is the largest value less than $$$v$$$, which is like a lower_bound and can be found efficiently. For all other values, $$$dp_i = dp_{i - 1}$$$. Finally, to keep the pairs increasing, you can naively remove the pair next to $$$(v[i], dp_i[v[i]])$$$ while it is smaller. Since each pair can be removed only once, you'll be doing it at most $$$n$$$ times in total.

          It can be efficiently implemented with a set, see my submission

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

            thank you very much! orz

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

            where a is the largest value less than v

            shouldn't it be largest value less than or equal to v because we want to include non-decreasing part of array in the dp?

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

              In French less than means less than or equal to and positive means non-negative ... As always, blame it on the English

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

            Thanks for the idea. Here is an alternative implementation.

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

            This is kind of like dynamic Pareto frontier maintenance, basically “maintain only states that are not strictly worse than another in all dimensions,” and you enforce global monotonicity of both dimensions by maintaining a ordered set of one dimension + local dominance pruning of the other dimension per operation, after correctly placing the element based on first-dimension-order via set insertion. It can be seen as a generalized and more powerful version of monotonic stack. Cool technique!

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

      It can be solved for $$$ n \le 2 * 10^5 $$$, however we decided, that there is no huge difference, so we chose the easier version

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

What should Output for test case :

  • 1
  • 3 4 5
  • 2 4 3

for E. khba Loves to Sleep! My accepted code gives 0 1 2 3 but i think this should 0 1 2 5

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

    Both are correct

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

      why ? 0 1 2 5 should correct because 5 has 1 minimum distance but 3 hasn't. so second one is more optimal

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

        You have to consider the minimum time travelled by any person.

        For 2,4,3 : 0 1 2 3 -> The guy at position 3 requires 0 seconds. 0 1 2 5 -> The guy at position 2 requires 0 seconds as there is a teleporter on position 2 , so they both are equivalent.

        In this case you have to place 4 teleporters and x=5 so you have no way of achieving a better answer.

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

          No see for 0 1 2 3 output we have - Minimal times for friends are [2,1,0,0], respectively. and for 0 1 2 5 output we have - Minimal times for friends are [2,1,0,1], respectively. so last one (for 5) have better answer.

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

            Yes you are right. But you need to maximize of minimum of Minimal times. Example minimum of [2, 1, 0, 0] is 0. And minimum of [2, 1, 0, 1] is 0. So they are same. Because you see only minimum time instead of all times.

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

            The problem wants you to maximise the time required by the first guy to reach a teleporter, which means you need to maximise the minimum, the rest are inconsequential.

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

AK the contest!, Thanks for this interesting contest

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

editorial for problem -G is pretty clever and simple!
thanks!

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

Figured a greedy approach for problem E choose the value with the maximum possible min distance from each $$$a_i$$$.

A simple proof to see it works is — say we have an optimal set $$$k$$$ which does not include point with the max distance say $$$k_m$$$, then we can simply replace any point in $$$k$$$ with $$$k_m$$$ and we still have an optimal set. This works for every possible stage.

Binary search gives the closest distance from a given position, we can use that as the cmp for a priority queue. Another greedy choice, rather than inserting every point in range [0,x], insert 0, x, and the midpoint(s) of $$$a_i$$$ and $$$a_{i-1}$$$ for $$$(1≤i≤n-1)$$$ (0-indexed) since one of those points have the max distance.

While we still have elements left to choose, pick the top priority say $$$c$$$, add to the result and then insert $$$c+1$$$ and $$$c-1$$$ as long as they are valid meaning in range [0,x] and not already chosen (my submission conveniently skipped this check, but still AC'd).

https://mirror.codeforces.com/contest/2167/submission/346322280

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

Why does the answer to E need to add n?

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

In the problem F, don't we have to consider the case when the number of nodes outside of node v + number of nodes in one of the subtree of node v >= k, then when the nodes in the remaining subtrees of v becomes a root, node v contributes to the answer, right? it is not covered in the editorial, or did I miss anything?

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

    After seeing your question, I had the same doubt. Later I realized that this answer is included in the calculation of v's child nodes. When sz[v] >= k, the contribution of v to the n-sz[v] nodes outside v's subtree is added. When n-sz[v] >= k, the contribution of f[v] to the sz[v] nodes within v's subtree is added. In other words, when traversing each v from 1 to n, the calculation includes v's contribution to nodes outside its subtree and f[v]'s contribution to nodes within its subtree, but the contribution of v itself is not accounted for in either v's calculation or its child nodes' calculations. This is why we need to add n to the ans when outputting the result.

    看到你的提问之后我也产生了相同的疑惑,后来我发现这种答案包含在v的子结点的计算中,sz[v]>=k时,将v对除v子树之外n-sz[v]个结点的贡献加入了,n-sz[v] >= k时,将f[v]对v子树中sz[v]个结点的贡献加入了,也就是说在从1到n遍历每一个v时,计算了v对v子树之外结点和f[v]对v子树中结点的贡献,而对v本身的贡献无论在v的计算中还是在v子结点的计算中都没有计入,这也是为什么要在输出时给ans加n

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

The prime enumeration in the solution for Problem D missed 47.

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

Fast and well-written editorial. F is such a good and basic problem of root-changing DP!

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

can anybody tell me why we are adding n to the answer in the problem F?

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

    That n accounts for making each of the nodes 1,2,...,n as the root. Since k is atmost n, the root r will be included (take one of the nodes as the root, and arbitrarily select rest of the k — 1 nodes).

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

    When sz[v] >= k, the contribution of v to the n-sz[v] nodes outside v's subtree is added. When n-sz[v] >= k, the contribution of f[v] to the sz[v] nodes within v's subtree is added. In other words, when traversing each v from 1 to n, the calculation includes v's contribution to nodes outside its subtree and f[v]'s contribution to nodes within its subtree, but the contribution of v itself is not accounted for in either v's calculation or its child nodes' calculations. This is why we need to add n to the ans when outputting the result.

    sz[v]>=k时,将v对除v子树之外n-sz[v]个结点的贡献加入了,n-sz[v] >= k时,将f[v]对v子树中sz[v]个结点的贡献加入了,也就是说在从1到n遍历每一个v时,计算了v对v子树之外结点和f[v]对v子树中结点的贡献,而对v本身的贡献无论在v的计算中还是在v子结点的计算中都没有计入,这也是为什么要在输出时给ans加n

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

What is F talking about? I read it once and once but havn't understand the explanation of test case yet.

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

Aside from the testing speed, everything else is good.

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

Hello can anyone help me regarding the problem G , i don't understand how this solution(editorial) guarantees correct ans is there any proof for eg what should be the ans for a={1,1,1,17,1,1,1},c={1,1,1,10000,1,1,1}

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

why problem A tagged "2-sat"?

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

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //this is the code

include <bits/stdc++.h>

using namespace std;

int main() { int t; cin >> t; while (t--) { int n, k; cin >> n; vector a(n); vector<pair<long long, int>> vpp(n); vector d(n);

for (int i = 0; i < n; i++)
    {
        cin >> a[i];
    }

    for (int i = 0; i < n; i++)
    {
        cin >> d[i];
    }

    long long sum = LLONG_MAX;
    long long check;
    long long e, t;

    for (int i = 0;i < n; i++)
    {
        check = 0;
        e = a[i];
        t = a[i];
        for (int j = i + 1; j < n; j++)
        {
            if (a[j] <e)
            {
                check = check + d[j];
            }
            if (a[j] > e)
            {
                e = a[j];
            }
        }
        for (int j = i - 1; j >= 0; j--)
        {
            if (a[j] >t)
            {
                check = check + d[j];
            }
            if (a[j] < t)
            {
                t = a[j];
            }
        }
        sum = min(sum, check);
    }

    cout << sum << endl;
}

} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Please tell me whats wrong in this solution for question G of the contest

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

F why ans+n ,i wonder why add n

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

    as the condition $$$k \le n$$$ is always true, every root can the lca of some subset of nodes

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

I still can't understand the solution for problem E , help me coders.

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

    Instead of thinking about k first, think that for an assumed minimum distance m, is it possible to fit at least k teleports on the number line. If it is true, we search the greater search space for greater (more likeable) values of m, if not we go and choose the lesser search space.

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

In the editorial for F, It says when outside the subtree of i, if n- szi >= k, then we can choose any root in subtree of i and szi >= k hold, I agree with that. But what about the cases when n — szi <= k , if I choose root as someone in its subtree and after that the size of the subtree of i becomes >= k ? Why are we not taking that case

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

    "if I choose root as someone in its subtree and after that the size of the subtree of $$$i$$$ becomes $$$ \gt = k$$$" it will not, if I understood your problem corrently. I'm sorry if I misunderstood.

    Think about it. How will it change? If you root differently from current rooting by choosing a node from a certain path's, the previous root's subtree will be the other unexplored/branched-out portion. In other words, if a tree starts like

    .....1

    /....|....\

    2....3.....4

    then, any new root chosen from 2's branch will have a fixed size subtree in node 1, and that size is always sz(3) + sz(4) + 1 (the node 1 itself).

    Hope it helps. Again, not sure if this is what you were thinking about, but I tried.

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

      yes exactly so what if 1 + sz(3) + sz(4) becomes >= k, but the solution will does not account for this condition, if only says n — sz(1) >= k

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

        We actually need to check n - sz(2) >= k if we are talking about my example. It means that for node 1, if node count except 2's path (thus n - sz(2)) is bigger than k, then all nodes in that subtree will have current node (node 1) as their answer if we make them root. Repeat that for all the paths, and repeat all of it for all current nodes.

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

Problem F seems to be intuitively easier compared to problem G (because I didn't even think about reversing the DP as to finding max instead of plugging directly from the problem where I have to find min) but why is it the case that there seems to be much more people solving problem G instead of F?

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

G is easy with n <= 8000. imo n <= 1e5 should have been a better constraint, and more fitting for this position.

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

In problem E, we can do a different logic in the binary search.

It’s related to the union of the forbidden segments.

For each i, the forbidden segment is [a[i]−dif+1,a[i]+dif−1].

The union will be: for each left endpoint we take the maximum right endpoint, and then we create an array that doesn’t contain intersections between segments.

Then, we have forbidden segments [x1, x2], [x3, x4], [x5, x6],.. we take the teleports from the segments [x2+1,x3−1],[x4+1,x5−1]..

This is my submission 350253562

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

In the editorial of problem F, I think it should be better to state: if $$$n - sz_i \ge k$$$ holds, then $$$sz_{p_i} \ge k$$$ for roots in the subtree of $$$i$$$. (here $$$p_i$$$ is $$$i$$$'s parent in the rooted tree.)

i.e when $$$n - sz_i \lt k$$$ we might be missing contributions of $$$i$$$ but we are not missing contributions of $$$p_i$$$. So in the algorithm we are actually adding the parent's contributions.

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

For question G why this Top down approach fails ...irrespective of TLE or MLE...this fails because it gives wrong answer but how what is the flaw in this solution-->

#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll compute(vector<ll> &dp, vector<int> &values, vector<int> &costs, int index, int pre_val)
{
    if (index < 0)
        return 0;
    if (values[index] == pre_val)
    {
        // we must incude it
        if (dp[index] != -1)
        {
            return dp[index];
        }
        else
        {
            return dp[index] = costs[index] + compute(dp, values, costs, index - 1, values[index]);
        }
    }
    if (values[index] < pre_val)
    {
        // wehave option to take it or leave it
        if (dp[index] != -1)
        {
            return max(dp[index], compute(dp, values, costs, index - 1, pre_val));
        }
        else
        {
            dp[index] = costs[index] + compute(dp, values, costs, index - 1, values[index]);
            return max(dp[index], compute(dp, values, costs, index - 1, pre_val));
        }
    }
    if (values[index] > pre_val)
    {

        return compute(dp, values, costs, index - 1, pre_val);
    }
}
int main()
{
    int t, n;
    cin >> t;
    while (t--)
    {

        cin >> n;
        vector<int> values;
        vector<int> costs;
        int a;
        ll max_keep{};
        for (int i = 0; i < n; i++)
        {
            cin >> a;
            values.push_back(a);
        }
        for (int i = 0; i < n; i++)
        {
            cin >> a;
            max_keep += a;
            costs.push_back(a);
        }
        vector<ll> dp(n, -1);
        max_keep -= compute(dp, values, costs, n - 1, 8000);
        cout << max_keep << endl;
    }

    return 0;
}

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

hi. how am i supposed to know if 53 will be the number upto which the product of primes will exceed 10^18? is this a regular pattern?.(ps. sorry if the question seems dumb, im a newbie)

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

    The guy in the video explains why. If you multiply all the prime numbers till 53 it can cover all numbers up to 10^18.

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

    In cases like this, you can write a quick program to check. Shouldn't take any longer than a minute if you're comfortable with programming:)

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

    instead of trying to find the exact number (53), can we just see numbers which contain 10 in them ? there are more 18 numbers which have 10 in them in the primes < 100. (11, 13, 17, ... 97), so checking for primes < 100 is enough.

    ofcourse this is slower and increases the time complexity by a constant but a easier intuition.

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

In question D what must be the output for the array 6, 18, 30. I think it should be 4. But the according to solution it is 5. How? I think there is a glitch.

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

    $$$gcd(4,30)=2$$$

    $$$gcd(4,18)=2$$$

    $$$gcd(4,6)=2$$$

    Hope this helps!

    Additionally, the answer cannot be composite, as for any composite number, there exists a prime that is a better choice.

  • »
    »
    5 months ago, hide # ^ |
    Rev. 2  
    Vote: I like it 0 Vote: I do not like it
    1. question requires that atleast for one number in the array for which gcd(x, num) should be 1. [6, 18, 30] and x = 4 does not satisfy this.

    2. if there is atleast one odd number in the array, answer must be 2 as gcd(2, odd) = 1

    3. if every number in the array is even, then we must find the smallest odd number (to have gcd as 1). for every composite odd number, there is always a smaller prime number which also gives gcd as 1. so it comes down to finding the smallest prime number.

    4. how many prime numbers to check for ? primes number < 100 are enough because

    • if the number is missing a prime (<100), then that is the answer.
    • but if it is not missing any prime (2 * 3 * 5 .. 97), then number is way greater than 10^18, which is not possible because of the constraint.
    • till 53 is enough to check but instead of calculating the above value, we can look at numbers which contain 10, and there are more than 18 numbers in primes (<100) which have 10 in them, so multiplying them would give > 10^18.