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

Автор Vladosiya, история, 4 года назад, По-русски

1741A - Сравни размеры футболок

Идея: MikeMirzayanov

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

1741B - Смешная перестановка

Идея: MikeMirzayanov

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

1741C - Минимизируй толщину

Идея: MikeMirzayanov

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

1741D - Маша и красивое дерево

Идея: Gornak40

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

1741E - Передача последовательности по сети

Идея: MikeMirzayanov

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

1741F - Разноцветные отрезки

Идея: MikeMirzayanov, ibraevdmitriy

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

1741G - Кирилл и компания

Идея: Vladosiya

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

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

another opportunity to feel dumb

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

G is good and can be extended to weighted graph

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

One of the best editorial thanks for this....****

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

Nice contest and great editorial!

F a little harder

Nice G

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

If we replace mar = *max_element(...) with *min_element(...) in problem D, we are getting AC in both cases. I did min element there so someone can just give example or any explanation why is it working? Thanks in advance :)

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

    If the tree should pass the sanity check (i.e. Answer is not $$$-1$$$), then any comparison between the left subtree and the right subtree should return the same result. You can observe this by trying to construct the input from the sorted order $$$[1,2,\cdots,m]$$$. You can see that there is no way to move elements from the left subtree to the right subtree (or vice versa), other than to swap the two subtrees entirely. Therefore, the comparison returns $$$L \lt R$$$ if the two subtrees didn't swap, and $$$L \gt R$$$ if they did swap.

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

Can someone explain F editorial? Thanks.

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

    Imagine a segment $$$S$$$ with left and right points being $$$S_l$$$ and $$$S_r$$$. Now, think about all different segments that have it's left points before (or exactly equals) $$$S_r$$$. You will notice that all those segments (including $$$S$$$) are candidates to be the closest to the left point of $$$S$$$ aka $$$S_l$$$. Or even intersecting with $$$S$$$.

    When you realize that, the solution that comes in mind is: for every segment $$$S$$$, search among all segments with left points smaller than or equals to $$$S_r$$$ with different color, the one with highest right point $$$R_{max}$$$. After that, check if $$$R_{max} \lt S_l$$$ (some distance) or $$$R_{max} \ge S_l$$$ (intersecting segments).

    Of course this solution gives you a TLE. However, as we want to know all segments with left points smaller than or equals to our current right point $$$S_r$$$, the idea is iterate over all segments $$$S$$$ in increasing order of right points. Also, keep a pointer to the segments with left points $$$\leq S_r$$$ already considered (to find $$$R_{max}$$$). Update this pointer as you walk through values of $$$S_r$$$.

    The remaining part of the solution is explained in the editorial. That is the part that was difficult for me to understand as well. Hope it heps.

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

Video Editorial for Chinese:

Bilibili

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

Wanted to reach specialist using div3 as a ladder, instead got negative delta. bleh. Need to grind more.

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

Problem D. To decide to swap or not we do not need to calculate maximum. Enough to compare the first element with middle value.

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

$$$C$$$ and $$$D$$$ could've been swapped, at least in my opinion $$$D$$$ is way easier than $$$C$$$.

»
4 года назад, скрыть # |
Rev. 12  
Проголосовать: нравится +1 Проголосовать: не нравится

I have another solution for C:

We calculate the sum of the whole sequence, and consider its divisors: For every divisor $$$x$$$, we check whether we can divide the sequence into segments of sum $$$x$$$, and calculate the length of the longest segment. Doing that for every divisor gives us the time complexity of $$$O(1344\times n+\sqrt{n\times a_i})$$$, which is still good enough to get AC.

Solution: 175584583

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

What is wrong in my submission for problem D? 175630153

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

There's another solution to B, which I believe to be more intuitive.

If n equals 3 print -1.

If n is even, then the permutation looks like this:

$$$p = {(n), (n - 1), ...(n / 2 + 1), (1), (2), ... (n / 2)}$$$

If n is odd, just print the permutation for n + 1, but without the first element, which will always be equal to n + 1, so the permutation is valid.

Solution: 175595206

  • »
    »
    4 года назад, скрыть # ^ |
     
    Проголосовать: нравится +1 Проголосовать: не нравится

    In my opinion your solution seems a little bit more complicated than necessary and than the one given in the editorial.

    I did something similar, but instead of doing

    p = n, n-1, ..., n/2+1, 1, 2, n/2

    I just did

    p = n, n-1, 1, 2, ..., n-2

    That way it's easier to implement and this works for both even and odd values of n, so you don't need to handle those cases separately

    Solution: 175582981

    Anyways, it really doesn't matter much...

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

Does anyone know what the 17th test case of test case 3 for F is? 175777495

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

I have another solution for G. It got AC but I'm not sure if it is actually correct.

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

For problem D, we can first check all leaves. Start from a1, we consider every pair (ai,ai+1), it must be like (x,x+1) or (x+1,x), if not, we cannot sort it. Otherwise, when the form is (x+1,x) we are supposed to swap it. Put (x+1)/2 to its father node. After do this we get a new array which length is n/2. And repeat it until the array length is 1. link

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

For problem D, we can first check all leaves. Start from a1, we consider every pair (ai,ai+1), it must be like (x,x+1) or (x+1,x), if not, we cannot sort it. Otherwise, when the form is (x+1,x) we are supposed to swap it. Put (x+1)/2 to its father node. After do this we get a new array which length is n/2. And repeat it until the array length is 1. link

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

Wouldn't the complexity remain O(mn) for D even after pre-calculating min and max for each vertex since we are swapping elements at each level?

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

    We do not necessarily have to swap all elements of the left/right subtree. I used a bottom-up iterative approach for this. We enumerate $$$k$$$ as powers of two (including one) less than $$$m$$$. And starting from $$$k=1$$$, we try to fix the order of $$$A_{2kx}$$$ and $$$A_{2kx+k}$$$. Now we can see that the indices we wil be comparing on the next step will be a subset of the current step. (Think of it as arithmetic progressions of $$$d=1,2,4,\cdots$$$) This is due to the fact that if the subtrees below are sorted, then we can compare the leftmost element to see whether we need a swap or not. And as we will refer to a subset of the current step on the next step, just swapping the two elements suffices for counting the swaps. The sanity check is done by checking a certain invariant property which is true when the subtrees below are sorted and the tree is made from a perfect binary tree: $$$|A_{2kx}-A_{2kx+k}|=k$$$. This solution is $$$O(m)$$$, you can check my submission (Python:175604510, C++:175815111) for further details.

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

Can anyone explain why 175793640 gives MLE on test 24 (problem G)? It works for other test cases which have higher n and m.

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

I like E, pretty standard and good

»
4 года назад, скрыть # |
Rev. 5  
Проголосовать: нравится +3 Проголосовать: не нравится

Here's an alternative solution to F w/ $$$O(n\log n)$$$ time complexity and less code.

As done in the editorial, traverse the segments after sorting by left coordinate, and again after transforming $$$(l,r)$$$ to $$$(-r,-l)$$$. Instead of keeping track of 2 maximal segments, though, we keep track of the rightmost endpoint of each color with a max segment tree, and when we are processing segment X, if the query result is to the right of X's left endpoint, we can set $$$ans[X]$$$ to 0, otherwise set $$$ans[X]$$$ to the distance between the left endpoint and the query result.

The above algorithm nearly works, except for when a segment is only adjacent to differently colored segments inside itself. Though, we can then use one additional check: the fact that if segment X contains the midpoint of segment Y, then segments X and Y intersect. This is also insufficient standalone as the converse is false, but kills the edge case. Using a std::multiset, we can perform it in $$$O(n\log(n))$$$.

Implementation: https://mirror.codeforces.com/contest/1741/submission/175824953

Alternative implementation, with an additional factor of $$$O(\log c)$$$ in space and time complexity, but uses no data structures outside std::set<int>: https://mirror.codeforces.com/contest/1741/submission/175826713

(EDIT: the use of a segtree can be circumvented in my original solution with the bitwise maximum technique in this implementation, which should also improve execution time. Though, that is something one would be far less likely to come up with in contest.)

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

Can someone help me understand the editorial for problem G? I'm not sure what the editorial is trying to say, and I'm finding it difficult to decipher the code in the given solution.

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

I would like to share my DFS solution approach for problem E. There can be at most O(2*n) valid subarrays. Each segment is consisted of 2 parts length and numbers. In a segment the length can be either on left or on right. Now, if we consider a[i] as one segment's length indicating cell, then the segment will be either of [i-a[i],i] range or of [i,i+a[i]] range. Let's consider each index as a node. If there are two nodes(segments) having range [i,R1] and [j, R2] where R1+1==j, then we will put an edge between them. Now, lets run a dfs from node 1. If we can reach the node (n+1), then answer is "YES", otherwise "NO". (n+1) is just a dummy node at additional index (n+1). My submission: https://mirror.codeforces.com/contest/1741/submission/175659624

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

Problem C can also be solved by considering all factors of the sum (sum of all elements of array), and trying to split the array for each factor. There can be maximum of log2(sum) factors making the complexity O(NlogN).

Here is my solution: https://mirror.codeforces.com/contest/1741/submission/175841633

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

    Actually the number of divisors of $$$N$$$ is not bound to be lower than $$$\log N$$$. We can use a number which is a product of many different primes for an example of this. Your statement is true for prime factors, but it is nowhere close to the truth for all factors. $$$d(N)\le N^{\frac{1.5379 \log(2)}{\log(\log(N))}}$$$ is a known upper bound for the divisor function for $$$N \le 3$$$, though. ($$$\sqrt[\leftroot{-2}\uproot{2}3]{N}$$$ is not a precise upper bound either, it is just an estimate)

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

Does anyone know subcase 26 in test case 3 for G? 176090403

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

176213193 which is my way to solve D using sparse table :)

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

.

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

271884281 I got a memory limit exceeded error on case 18, can somebody figure out what can I do to optimally run my code. Thanks !!!

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

The original solution to problem E is not so intuitive. There is another way to structure the DP. Each index (i) will either represent length of a segment to the right of it (then we can recursively call of f(i+a[i]+1) or will become part of a segment having it's length representation to the right (then we can see which index (j) to the right of it satisfies (j — a[j] == i).

Here is the Java code:

import java.io.*;
import java.util.*;

public class Main {
    static int M = 1000000007;

    public static void main(String[] args) {
        Scanner ab = new Scanner(System.in);
        int T = ab.nextInt();
        for(int test = 1; test <= T; test++) {
            int N = ab.nextInt();
            int[] a = new int[N];
            for(int i=0; i<N; i++) a[i] = ab.nextInt();

            ArrayList<Integer>[] b = new ArrayList[N];
            for(int i=0; i<N; i++) b[i] = new ArrayList<>();
            for(int i=N-1; i>=0; i--) {
                int idx = i - a[i];
                if(idx >= 0) b[idx].add(i);
            }

            int[] dp = new int[N];
            Arrays.fill(dp, -1);
            System.out.println(f(0, a, dp, b) ? "YES" : "NO");
        }
    }

    static boolean f(int i, int[] a, int[] dp, ArrayList<Integer>[] b) {
        if(i == a.length) return true;
        if(i > a.length) return false;
        if(dp[i] != -1) return dp[i] == 1;

        boolean ans = f(i+a[i]+1, a, dp, b);
        for(int j: b[i]) ans = ans | f(j+1, a, dp, b);

        dp[i] = ans ? 1 : 0;
        return ans;
    }
}

The arraylist (b) is used for precomputation so that we don't have to loop for every single index. It might look like O(N*N) time but it's actually O(N).

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

Problem Number D can be solved using Divide and Conquer..while merging the two subparts...we just have to check that the diff of the minimum of the two should be less than the size of the subproblem...if not return -1 which signifies that we it is not possible...like if the subarrays are — [1,2] and [7,8] then we cannot make it increasing in any number of operations..if it was [5,6] as left and [7,8] as right then it is correct if otherways return 1+left+right in recursive manner.... here is my code 323823012

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

time constraints for E is really tight.

topdown dp of the exact same implementation doesn't work. im getting TLE on test 20, i copy pasted that test and it runs 3ms on my laptop! how does that take more than 1 sec on your servers ?!