awoo's blog

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

2145A - Candies for Nephews

Idea: fcspartakm

Tutorial
Solution (fcspartakm)

2145B - Deck of Cards

Idea: BledDest

Tutorial
Solution (Neon)

2145C - Monocarp's String

Idea: fcspartakm

Tutorial
Solution (BledDest)

2145D - Inversion Value of a Permutation

Idea: BledDest

Tutorial
Solution (BledDest)

2145E - Predicting Popularity

Idea: adedalic

Tutorial
Solution (adedalic)

2145F - Long Journey

Idea: BledDest

Tutorial
Solution (Neon)

2145G - Cost of Coloring

Idea: BledDest

Tutorial
Solution (BledDest)
  • Vote: I like it
  • +56
  • Vote: I do not like it

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

G is pretty amazing and educational.

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

where can i find problems similar to D which don't scream DP but are/

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

    This problem reminded me of a problem from here https://cses.fi/problemset/task/2229

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

    IMO, this is the thing which is a bad habit in me. DP is a technique We don't need to think that wether a problem is DP or not in Disguise, its bad for Problem Solving. Problem Solving/CP is Seeing a Problem for what it is, drawing meaningful observations and then you observe some property and be like -> "Ohh!! I can handle this using Dynamic Programming" thats better. That will help you in solving Problem.

    D Spoiler
»
12 months ago, hide # |
 
Vote: I like it +4 Vote: I do not like it

Missing editorial for F btw

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

I was looking forward to editorial of F,please post it.

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

Fast Editorial! Nice!

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

D is a beautiful problem, but can we do better than $$$O(N^4)$$$. Overall B > C. I think E is solvable by SegBeats thought its overkill and I am getting TLE. Binary search with Segtree also Works

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

F is made easier by the fact that the greedy is correct (since $$$x$$$ and $$$x + 1$$$ can't both be trapped at the same time, it is optimal to advance whenever possible).

However, we can solve a more general version of the problem where there is no greedy, for example when instead of losing if $$$x$$$ mod $$$a_t = b_t$$$ at time $$$t$$$, we lose if $$$x$$$ mod $$$a_t \in B_t$$$ with $$$B_t$$$ a subset of $$$[0, 1, ..., a_t - 1]$$$.

For $$$m \lt = LCM$$$, we can simply run a classic $$$dp[LCM][n]$$$ to find the minimum distance from $$$(0, 0)$$$ to any state. For bigger $$$m$$$ however, we need to go through the torus multiple times (since the dp is cyclic in both variables, the graph looks like a torus).

For that, we can run the dp once to find the min distance from $$$(0, 0)$$$ to $$$(LCM, t)$$$ for each $$$t$$$, then run the dp again this time starting from $$$(0, 1)$$$, $$$(0, 2)$$$, and so on, until we have all minimum distances between $$$(0, i)$$$ and $$$(LCM, j)$$$ for $$$0 \leqslant i, j, \lt n$$$.

Once we have this $$$n * n$$$ matrix, it allows us to connect the start of the torus to its end, and all we need to do is to exponentiate it to the power $$$m / LCM$$$, and run the dp one final time to go through the last $$$m$$$ mod $$$LCM$$$ steps.

Time complexity : $$$O(n^2LCM + n^3log(m))$$$

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

Can anyone explain why order doesn't matter in problem B?

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

    Because k<=n that means a same card can't be removed from both top & bottom, even if you do operation in any order. And all operation '2' will lie in middle of removed cards.

    for eg., 2210 for any n>k After first 2 operation you are unsure about top 2 & bottom 2 cards but after 3rd operation you are sure at least 1 card is removed from bottom & after 4th you are sure at least 1 card is removed from top.

    It is same for 1022 or 1220 Here also you are sure about 1 top & 1 bottom card.

    And n==k is edge case where all cards are removed because you are removing n cards in total so type of operation & order of operation doesn't matters.

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

D can be brute forced for n<80 in python (probably much higher in C++).

If you have answer for all k for a given n, you can find a valid answer for all k which have a valid solution for n+1 by just brute forcing n+1 at every possible position in answer for every k for n then compute the k for that permutation. Given how low the constraints are this will work just fine.


Python brute force solution:
»
12 months ago, hide # |
 
Vote: I like it +1 Vote: I do not like it

I don't understand D T_T. How do people come up with this shi

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

stupid 4 pointer idea for B 342285913

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

Why is $$$n + m - \min(x, y)$$$ the number of operations for problem G?

Isn't it best to select the smallest one if there are $$$x$$$ rows and $$$y$$$ cols with color 1? The number of operations required, in my opinion, is $$$n + m - x - y + \min(x, y) = n + m - \max(x, y)$$$.

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

Can please anyone explain why this one passes the sample case but fails on test 2, is it my approach is wrong or I missed the edge cases? for C:

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

#define int long long
#define all(v) (v).begin(), (v).end()
#define pb push_back
#define endl '\n'

void fastio() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
}

int32_t main() {
    fastio();

    int t;
    cin >> t;
    while (t--) {
        int n; cin >> n;
        string s;
        cin>>s;
        int ta=0,tb=0;

        for(int i=0;i<n;i++){
            if(s[i]=='a')ta++;

            else tb++;
        }

if(ta>tb){

    
priority_queue<int> pq;
stack<int> st;

for(int i=0;i<n;i++){

if(s[i]=='a' && i!=(n-1)){
st.push(i);
}

else{
    pq.push(st.size());
    if(!st.empty()){
    st.pop();
    }
}
}

if(pq.top()<abs(ta-tb)){
    cout<<"-1"<<endl;
}

else{
    cout<<abs(ta-tb)<<endl;
}

}


if(ta<tb){

priority_queue<int> pq;
stack<int> st;

for(int i=0;i<n;i++){

if(s[i]=='b' &&  i!=(n-1)){
st.push(i);
}

else{
    pq.push(st.size());
    if(!st.empty()){
    st.pop();
    }
}
}

if(pq.top()<abs(ta-tb)){
    cout<<"-1"<<endl;
}

else{
    cout<<abs(ta-tb)<<endl;
}

}

if(ta==tb){
    cout<<"0"<<endl;
}
    }

    return 0;
}


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

I think problem B can be solved by Brute-Force and Deque data structure. Because the bottom card removal operation can cost O(n)(remove arr[0] in array ) and repeating it many times like that can make the complexity O(n^2) and it will be TLE. We can solve this problem by Deque which makes the bottom card removal only have complexity O(n) and helps the complexity of the code from O(n^2) to O(n)

This is just a suggestion on the solution of problem B improved from Brute-Force, please do not downvote me

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

There should be modification in solution of D!

We have to fill up dp & p earlier not in the loop as it will give TLE. I tried solution of editorial its giving TLE. But, if you calculate it earlier then it will work.

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

"There are other ways to solve this problem, for example, with functional graph cycle detection or fast matrix exponentiation, but in my opinion, this approach is the easiest to implement."

What would the functional graph cycle detection solution be like?

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

I had similar key idea for D, but with little bit different implementation. Our final permutation (if it exists) consists of several sorted segments with various length. Each of them contribute final answer by minus n*(n-1)/2, so we need to find segments whose sum equal to n*(n-1)/2 — k. Thus we can use knapsack dp to brute force all possible length and find their numbers and length. It will look like dp[i][1][2][3]...[30] right from 1 to n, i represent sum and left 30 numbers are counters of segments with length of its corresponding index. The transition is simple, just like in an ordinary knapsack, taking value from dp[i-op] and changing all its numbers with adding +1 to chosen length. Oh and dp itself is the sum of the length of the taken. So in the last step we just check whether dp[n*(n-1)/2 — k][0] is less or equal than n, and building permutation just like in editorial. Link Here is submission for more details.

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

It is sad that there is no interactive problem in this contest :(

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

Could someone clarify what the editorial author meant when they said "Iterate over K — the length of the next sorted block"?

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

Can someone please tell what was wrong with my solution in "problem C" as I use d the same concept , stored all the consecutive a's and b's in map and as we know we can only remove once hence I found the difference between their counts and tried to find if it is present in the map.

#include<bits/stdc++.h>
using namespace std;
 
 
int solve()
{
    int ans = 0;
 
    int n;
    cin>>n;
    string s;
    cin>>s;
 
 
    //Use the concept of prefix sum here
    //  use map to store them 
    unordered_map<int,int> mpp_a;
    unordered_map<int,int> mpp_b;
int c_a = 0;//total count of a
int c_b = 0; //total count of b
if(s[0]=='b')   c_b++;
else   c_a++;
int count  = 1;

    for(int i=1;i<n;i++)
    {
    if(s[i-1]==s[i])
    {
        if(s[i]=='b')
        {
            c_b++;
count++;
        }
        else{
            c_a++;
            count++;
        }
    }
    else{
        if(s[i]=='b')
        {
            c_b++;
mpp_a.insert({count,-1});
count=0;

        }
        else{
            c_a++;
mpp_b.insert({count,-1});   //Here we find the consecutive sequence ends and hence  I append it to map
count=0;
        }
    }
    }
 
    //Precomputing done
if(c_a>c_b)
{
    int diff = c_a &mdash; c_b;
if(mpp_a.find(diff)!=mpp_a.end())
{
   return diff;
}
else{
    return -1;
}
}
else{
int diff = c_b &mdash; c_a;
if(mpp_b.find(diff)!=mpp_b.end())
{
   return diff;
}
else{
    return -1;
}
}
 
return -1;
}
 
 
int main()
{
int t;
cin>>t;
 
while(t--)
{
cout<<solve()<<"\n";
}
 
    return 0;
}
»
12 months ago, hide # |
 
Vote: I like it +8 Vote: I do not like it

Just realize, the DP in G is just ordered $$$k-1$$$ partitions of a set with $$$ n-x+m-y $$$ elements.

set partitions could be calculated recursive in $$$O(n^2)$$$: $$$ part(n, k) = part(n-1, k-1)+k*part(n-1, k) $$$

Very educational~

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

Can someone guide me on how to approach generation based problems? For example, Question D in this contest, where you are asked to generate an array that satisfies certain conditions. How should I approach these types of problems? If it’s too much to explain in a comment, a link to a post or tutorial would be appreciated.

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

Why greedy doesn't work on D?

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

Hello, I received a message that my submission (342267062) coincides with submission 342268142 from another account. Both accounts (Mim5270 and akthermim) actually belong to me. I understand now that having multiple accounts and submitting the same solution was a mistake — I did not intend to break any rules or gain an unfair advantage. I sincerely apologize for the violation and assure you it won’t happen again. Please consider this my explanation. I will only use one account from now on. Thank you for your understanding.

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

My 342314871 for D without any DP (there is dp in my code but its just (i * (i — 1)) / 2)

I'm using brute force and check all possible set of length's for increasing subsegments.

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

Here is a soltion to solve problem 2145D - Inversion Value of a Permutation without using DP.

First,transform the problem meaning in the same way as the solution. We need to select some items which has $$$i$$$ value and $$$i+1 \choose 2$$$ weight and make the sum of value equal n and the sum of weight equal k.

Second,to do this,we have noticed the partition of $$$30$$$ is less than $$$6000$$$! So we can just use the brute force to solve this problem.

342894423

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

    i found a pretty ez dp solution which is kind of take it or leave it approach that helps find the position of the inversions , and you can just construct the permutation using these inversions with a little bit of dfs ahh approach https://codeforces.me/contest/2145/submission/343178829

    its another nice solution all in all that requires no math or any extras , keeping it simple enough

    let me know what you think

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

Can someone tell me what is wrong with this code 349836610 for problem D

i got WA on this testcase:

1 5 10

but when i ran it has the right output

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

2145C is a very good ques , it seems like easy on first go. but it quite different to think on first hand while u are writing code their are two -1 testcases wont work , it took around 2 hours for the whole code but took 5-6 hours of effort to deal with that -1 testcase :(. but it was worth the time

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

In F,the "at the end of moves",is it mean "at the end of turns"?

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

Nice and elegant solution for D. But I'm lacking intuition why is it possible to construct any number using sum of $$$\frac{i_1*(i_1-1)}{2}+\frac{i_2*(i_2-1)}{2}+...$$$ and if it's not possible, then why are we certain that it's not possible to construct the answer in other way than in the editorial?

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

B is dog shit