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

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

Всем спасибо за участие! 👊👊👊

2121A - Письмо домой

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

2121B - Выше облаков

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

2121C - Тем, кто с нами

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

2121D - 1709

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

2121E - Спонсор твоих проблем

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

2121F - Ямакаси

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

2121G - Гэнгста

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

2121H - Ice Baby

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

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

speedyy voventa

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

H code in the tutorial is smaller than my A's . Wth :/. nvm good questions

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

E can also be solved by randomly sampling 1000 numbers per testcase and seeing what the minimum score of these numbers is. Enjoy :D 324927463

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

For $$$E$$$, I generated $$$100$$$ random numbers $$$x$$$ in the range $$$[l, r]$$$ and took the minimum $$$f(l, x) + f(x, r)$$$ over all of them. I think that the worst-case probability that some $$$x$$$ works is $$$(\frac{4}{5})^9$$$ (or around $$$13\%$$$) because, in most cases, it seems like each digit of $$$x$$$ has a $$$\frac{4}{5}$$$ chance of not being equal to either of the corresponding digits of $$$l$$$ and $$$r$$$. So the probability that the solution fails a testcase might be $$$(1 - (\frac{4}{5})^9)^{100} \approx 5 \cdot 10^{-7}$$$.

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

in problem D why simply sorting a and b and then swaping is enough. can someone explain me clearly why swaping in last will not violate our conditions .?

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

    Let $$$a$$$ and $$$b$$$ be the arrays after sorting, but before swapping.

    Then for any $$$i$$$, we have that $$$\min(a_i, b_i) \leq a_i, b_i$$$. But at least one of $$$a_i$$$ or $$$b_i$$$ must be smaller than $$$\min(a_{i+1}, b_{i+1})$$$, because one of them was placed before $$$\min(a_{i+1}, b_{i+1})$$$ whilst sorting. So we have that the mins are increasing.

    By similar reasoning, for any $$$i$$$, we have that $$$\max(a_i, b_i)$$$ is less than at least one of $$$a_{i+1}$$$ or $$$b_{i+1}$$$ because $$$\max(a_i, b_i)$$$ was placed before one of them whilst sorting. Since we have that $$$a_{i+1}, b_{i+1} \leq \max(a_{i+1}, b_{i+1})$$$, we have that the maxes are increasing.

    So we have that $$$\min(a_1, b_1) \lt \min(a_2, b_2) \lt \dots \lt \min(a_n, b_n)$$$ and $$$\max(a_1, b_1) \lt \max(a_2, b_2) \lt \dots \lt \max(a_n, b_n)$$$, so if we place all of the mins in $$$a$$$ and all of the maxes in $$$b$$$, both arrays remain sorted.

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

    After sorting, we have:
    - a[i] < a[i+1] for all i
    - b[i] < b[i+1] for all i

    Now, when we decide to swap because a[i] > b[i], we need to verify that the swap won't violate the sorted order of either array.

    Swapping b[i] into a:

    We're putting b[i] in place of a[i]. Since we originally had b[i] < a[i] < a[i+1], it follows that b[i] < a[i+1], so inserting b[i] into a won't break the increasing order in a.

    Swapping a[i] into b:

    This is more subtle. It's possible that a[i] > b[i+1], which would break the sorted order in b. However, since b[i+1] < a[i] < a[i+1], on the next iteration (i+1), we will again encounter a[i+1] > b[i+1], and thus perform another swap. This chain reaction will make sure that the arrays remain valid.

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

    simple proof for min(a[i], b[i]) < min(a[i + 1], b[i + 1])

    d1 = a[i + 1] - a[i], d1 > 0

    d2 = b[i + 1] - b[i], d2 > 0

    min(a[i], b[i]) < min(a[i] + d1, b[i] + d2) because both arguments of min have increased

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

DEF were easier compare to normal div 3 , Instantly knew solution of D,E here (this doesnt happen usually)

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

Too much implementation based questions, I think 2.5 hours for this would've been better, the explanations are pretty short which is fine when someone who is experienced is reading them, but for most people it might easily not come to them. Hope next div 3 is better

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

It's actually crazy how beautiful the solution to H is...

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

Alternate solution for problem G:

Let dp[i] denote the sum of function f() over all substrings in prefix of i, i.e, $$$\sum f(s_l,s_{l+1},...,s_r)$$$$$$\forall$$$ l, r s.t. $$$1 \le l \le r \le i$$$. Let ans[i] denote the sum of function f() over all substrings ending at index i, i.e, $$$\sum f(s_l,s_{l+1},...,s_i)$$$$$$\forall$$$ l s.t. $$$1 \le l \le i$$$. Let pre[i] denote the prefix sum till index i, i.e, $$$pre[i] = \sum_{j = i}^{i} (s[j] == 1)$$$.

Final answer will be dp[n] and base case is dp[1] = 1 and ans[1] = 1 (assuming 1 based indexing).

Now suppose the $$$i^{th}$$$ character is a 1 (small change in sign when $$$s_{i} = 0$$$), then:

$$$dp[i] = dp[i - 1] + ans[i - 1] + \sum_{j = 1}^{i} (pre[i] - pre[j - 1] \gt i - j + 1 - pre[i] + pre[j - 1])$$$

$$$ans[i] = dp[i] - dp[i - 1]$$$

The summation equation basically accounts for all the +1's we do when attach $$$s_i$$$ to $$$s_{1, 2, ..., i-1}$$$.

We can rearrange the summation equation and then use (ordered) set optimization to quickly compute the dp :)

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

Problem G has solutions for O(n)

I a bit overkilled this task and wrote this O(n) solution that uses 2 stacks to recalculate the answer using information about the answer on the previous prefix. If you are interested in analyzing it, here is the code: 324911499.

But I found a more interesting and simpler for understanding solution that reaches O(n), written by Kilo_5723. This solution implements the same logic as the author's, but counts the sum of modules of the prefix with asymptotic O(n), instead of O(nlogn): 324868540

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

    That's a clever approach. Thanks for sharing it.

    I wanted to point out that the tutorial's solution can also be made $$$O(n)$$$ trivially by using a counting sort instead of a comparison-based sort, since all the elements are between $$$-n$$$ and $$$n$$$.

    In fact, you can think of Kilo_5723's solution as doing an online counting sort: at the end of the loop, the array val contains a count of the elements of pref in the tutorial. The “online” part is that he updates the total for each character processed, which is why there are only additions/subtractions and no multiplications.

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

    https://codeforces.me/contest/2121/submission/325347841

    Here's mine also with O(n) time

    Seems a little simpler

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

      Could you please explain how it works?

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

        Basically, when you have the answer to some prefix that is n characters long, to find the answer to prefix that is n+1 characters long(either adding a 1 or 0), all you need to know is what ranges have what ever character added as the (n+1)th as the most common character or have both 1 and 0 as the most common character. We can have an array of size n*2 +1 and have a middle index and move it up or down depending on if a character is 0 or 1, for instance down if 0, up if 1 as the most we can move up or down is n. In this case in the array whatever index we start on we can increment it, and keep track of how many increments (or just the sum) of the array on the left and right sides of the 'middle' index as for all the increments that where previously done on the right side, if the new character is 0, that new character is increasing the value of those sequences as those subsets had 0 most common character. The inverse is true for the left side. This is like dp where we are using our previous answer and adding onto it, with each new encounter during our iteration through the list.

        https://codeforces.me/contest/2121/submission/326062731

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

Господи, храни Гуфа

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

Solution for problem E, using digit DP

324944536

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

When will be the ratings updated? today i gave my first contest so

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

Does anyone have another way to solve H? The editorial is too hard for me XD

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

    I simply used a Lazy Segment Tree; after compressing all values, let $$$\mathrm{dp}[k][v]$$$ be the maximum length of a non-decreasing subsequence using the first $$$k$$$ intervals and ending in $$$v$$$.

    Initially (for $$$k = 0$$$), the maximum length is always $$$0$$$. For a fixed $$$k$$$, all non-decreasing subsequences ending in $$$[0; l]$$$ can be "extended" by one by simply appending $$$l$$$ to it. At the same time, all subsequences ending in $$$v \in [l; r]$$$ can be "extended" by $$$v$$$; two operations that can be easily implemented for a Segment Tree!

    So in the end, you simply maintain a Lazy Segment Tree containing all possible ending values and update that for each step in $$$\mathcal O(\log n)$$$ time.

    Submission: 324887791

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

Can anyone please tell why my solution is getting memory limit exceeded :(

https://codeforces.me/contest/2121/submission/324913725

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

170ms -> TLE ??? What the fucking original tests ???

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

170ms -> TLE ??? What the fucking original tests ???

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

Liked C

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

For problem F, I got a solution that uses sparse table + binary search. I thought that max[i -> x] for some x is monotonic. To my calculations, the time complexity should be O(n*log(n) + n*log^2(n)). But that gave tle on test 24 for some reason. Can anyone check my solution if I did calculate time complexity wrong or are there some bug in the code because I couldn't find anything https://codeforces.me/contest/2121/submission/324921228

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

Не смог решить задачу F, не знаю, почему моё решение не работало, хотя код был очень похож на код в разборе. 2 моё решение не прошло по времени :(

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

hi voventa I have solved the problem F and it also accepted but after system testing it showing TLE(time limit exceed) on test case 24 why ?

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

The problem G is the same as https://www.codechef.com/problems/SUMFSUB. There's not even a single change. The problem is fairly recent as well. I tried putting the problem statement of G in http://yuantiji.ac/en/ and it did not show me SUMFSUB. I can understand that no one is at fault here, but we need more powerful tools so that this does not happen in the future.

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

I believe I have another approach for Problem D (324890440) where we construct the first row as:

$$$1, 2, 3, \ldots, N$$$

and the second row as:

$$$N+1, N+2, N+3, \ldots, 2N$$$.

Here's an analysis of the worst-case scenario for my solution:

Worst-case scenario input
  • »
    »
    15 месяцев назад, скрыть # ^ |
     
    Проголосовать: нравится +1 Проголосовать: не нравится

    ItsNotMeItsYou I have also did the same thing in contest but got FST on system test-13 can you please tell me why it is failing My submission : My Submission

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

      You use operation 3 in the final step; I do it first.

      • »
        »
        »
        »
        15 месяцев назад, скрыть # ^ |
         
        Проголосовать: нравится 0 Проголосовать: не нравится
        #include <bits/stdc++.h>
        using namespace std;
        
        #define ll long long
        #define vi vector<int>
        #define vll vector<long long>
        #define vpii vector<pair<int,int>>
        #define vpll vector<pair<long long,long long>>
        #define pii pair<int,int>
        #define pll pair<long long,long long>
        #define mod1 1000000007
        #define mod2 998244353
        #define INF 1e18
        #define pb push_back
        #define ppb pop_back
        #define mp make_pair
        #define ff first
        #define ss second
        #define sz(x) ((ll)(x).size())
        #define all(x) (x).begin(), (x).end()
        #define rep(i,a,b) for(ll i=(a) ; i<(b) ; i++)
        #define all(x) (x).begin(), (x).end()
        #define yes cout<<"YES\n"
        #define no cout<<"NO\n"
        #define nl '\n'
        #define read(a) for(auto &it : a) cin>>it;
        #define printv(nums) for(int i=0;i<nums.size();i++) cout<<nums[i]<<" "; cout<<"\n";
        
        #ifndef ONLINE_JUDGE
        #include "template.cpp"
        #else
        #define debug(...)
        #define debugArr(...)
        #endif
        
        void solve()
        {
            int n;
            cin >> n;
            vi a(n),b(n);    
            read(a);
            read(b);
            vpii ans;
            for(int i=1;i<=2 * n;i++)
            {
                int idx = -1;
                char cur = 'a';
                for(int j=0;j<n;j++)
                {
                    if(a[j] == i)
                    {
                        idx = j;
                        cur = 'a';
                        break;
                    }
                }
                if(idx == -1)
                {
                    for(int j=0;j<n;j++)
                    {
                        if(b[j] == i)
                        {
                            idx = j;
                            cur = 'b';
                            break;
                        }
                    }   
                }
                int reqidx = (i <= n) ? i - 1 : i - n - 1;
                char reqA = (i <= n) ? 'a' : 'b';
                if(cur != reqA)
                {
                    swap(a[idx],b[idx]);
                    ans.pb({3,idx+1});
                }
                while(idx > reqidx)
                {
                    if(cur == 'a') ans.pb({1,idx});
                    else ans.pb({2,idx});
                    if(cur == 'a') swap(a[idx] , a[idx-1]);
                    else swap(b[idx] , b[idx-1]);
                    idx--;
                }
                while(idx < reqidx)
                {
                    if(cur == 'a') ans.pb({1,idx+1});
                    else ans.pb({2,idx+1});
                    if(cur == 'a') swap(a[idx] , a[idx+1]);
                    else swap(b[idx] , b[idx+1]);
                    idx++;
                }
            }
            cout << sz(ans) << nl;
            for(auto &[x,y] : ans) cout << x << " "<< y << nl;
        }
        
        
        signed main()
        {
            ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
            freopen("Error.txt", "w", stderr);
        
            int t = 1;
            cin >> t;
            for (int i = 1; i <= t; i++)
            {
                solve();
            }
        
            return 0;
        }
        

        Now it is taking more operations

        On that tc:13 previously it was taking 1810 op but not 2160

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

I like problem F

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

Overthinking did me a lot of harm in BCD...

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

Hi voventa, can you please add this blog to the contests materials? I didn't know this blog before I open the announcement that editorial is out

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

The (very neat) idea for problem H can also be used to solve this problem, and the code is not so different

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

Very nice contest!!!

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

Why does my solution 326223855 for F is giving tle despite being nlogn? Update : Missed the auto& it.

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

G can also be easily solved with a segment tree. First, get the sum of max counts for every substring containing the number at index 0. Keep track of the number of positive and negative relative one/zero counts for every substring. Then, we can remove the numbers from the left one by one. If we remove a 1, then decrease our result by the number of positive net sums and decrease all net sums by 1. If we remove a 0, then decrease our result by the number of negative net sums and increase all net sums by 1. Then the answer is the sum of each result after removing each number from the left n times.

Code: 326714584

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

Here is my O(n) solution for problem G.

    int n;
    cin>>n;
    string s;
    cin>>s;
    vector<stack<pair<int,int>>>delta_cnt_pairs(2);
    vector<int>exceed_cnt(2);
    int ans=0,sum=0,eq=0;

    for(auto i:s){
        int x = i-'0';
        int y = x^1;

        delta_cnt_pairs[x].push({1, eq + 1});
        exceed_cnt[x]+=eq + 1;
        eq=0;

        if(!delta_cnt_pairs[y].empty()){
            auto t=delta_cnt_pairs[y].top();
            delta_cnt_pairs[y].pop();
            if(t.first == 1){
                eq = t.second;
                exceed_cnt[y] -= eq;
            }
            else{
                delta_cnt_pairs[y].push({t.first - 1, t.second});
            }
        }
        sum+=exceed_cnt[x];
        ans+=sum;
    }
»
14 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Did anyone solve G using divide and conquer? I feel like it is possible but I am struggling with the implementation.

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

G is perfact,very interesting

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

damn good editorial

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

Problem H also can just be solved with segment tree beats, submission: https://codeforces.me/contest/2121/submission/358456170

»
5 месяцев назад, скрыть # |
Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится
Simpler implementation for Problem E
»
4 месяца назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

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

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

Task G can be solved using cartesian tree https://codeforces.me/contest/2121/submission/376262585 (I just again overkilled cause I didnt come up with anything simpler)