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

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

1989A - Поймай монетку

Идея: BledDest

Разбор
Решение (awoo)

1989B - Подстрока и подпоследовательность

Идея: BledDest

Разбор
Решение (Neon)

1989C - Два фильма

Идея: BledDest

Разбор
Решение (Neon)

1989D - Кузнечное дело

Идея: BledDest

Разбор
Решение (adedalic)

1989E - Расстояние до различных

Идея: BledDest

Разбор
Решение (BledDest)

1989F - Раскрась одновременно

Идея: BledDest

Разбор
Решение (awoo)
  • Проголосовать: нравится
  • +96
  • Проголосовать: не нравится

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

Fast tutorial

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

Interesting problemset

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

For problem D I kind of simulated the process by brute force, submission: 267758186

Notice that

  • if crafting and smelting cost $$$a_i - b_i$$$ of 2 kinds of weapons is equal, then it's never better to craft a weapon with a higher initial material cost $$$a_j$$$
  • if crafting and smelting cost $$$a_j - b_j$$$ of one kind of weapon is greater, it can only be useful to craft it if its material cost $$$a_j$$$ is lower

In my solution I simulate the process by going from lower operation cost $$$a_i - b_i$$$ and higher material cost $$$a_i$$$ to higher operation cost and lower material cost. On each step remaining metals with amount of ingots $$$c_k < a_i$$$ are useless for me, and any metals with $$$c_k \geq a_i$$$ will be reduced to metals with remaining quantity less than $$$a_i$$$, but at least $$$b_i$$$.

I was expecting this solution to get hacked or fail system tests, but somehow it's still standing (although I've seen some similar solutions getting hacked). After pondering on why did it not get TLE, I realized that each unique remaining value of $$$c_k$$$ will be considered at most once, and since there are at most $$$10^6$$$ unique values of $$$c_k$$$ the total time complexity will be amortized.

This solution is a result of me gaslighting myself that there are no more than $$$O(\sqrt{max(a_i)})$$$ unique differences $$$a_i - b_i$$$ (which is obviously not true).

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

    I did exactly the same, also waited to be hacked and then understood..

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

    can you please explain why you were able to use each value of ck atmost once? also, why does using lower_bound work here, shouldn't you use maximum amount of ingots for the best case (minimum difference)

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

      Let's go over from a brute force solution to a more optimized one step by step:

      • Iterating over all kinds of weapons and then for each weapon iterating over all kinds of ingots is $$$O(N \cdot M)$$$

      • Now let's group different kinds of ingots with the same remaining quantity together, since if you can calculate the amount of xp for a single kind of metal with remaining $$$c_k$$$ ingots, you can do the same for $$$X$$$ kinds of metals with $$$c_k$$$ remaining ingots. You could store counts in an array or in a map. Since there could be $$$M$$$ unique values of $$$c_k$$$ you still would be iterating over all kinds of metals, leading to $$$O(N \cdot M)$$$ complexity

      • Now get rid of the values which we cannot smelt anything from, on each step it's useless to consider values $$$c_k$$$ lower than $$$a_i$$$, this is where lower_bound comes in. Also notice that after each smelting operation all values $$$c_k \geq a_i$$$ will get mapped to some values strictly less than $$$a_i$$$. Picture it like this: you pick the largest $$$a_0$$$ first, you erase all values $$$c_k \geq a_0$$$, then you pick second largest value $$$a_1$$$ and erase all values $$$a_1 \leq c_k < a_0$$$, so on and so forth. In total you will not iterate over more than $$$max(a_i) = 10^6$$$ unique values of $$$c_k$$$ (probably even less under given constraints).

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

    I did what you stated in 267754245, but it got hacked :( Could anyone tell me what I missed in my solution?

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

    yeah, i also do the same thing and waited to be hacked. As the blogger said, this complexity is hard to think through on the field. But as long as we find this similar to the monotone queue optimization DP property, coupled with memory search, it is easy to amorize the complexity. If you were a hack, you would have to make each a minus b different and find a number, and then take the remainder of each of these A minus b's different, which is obviously impossible to do.

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

    actually the first observation isn't it better to use the high initial material cost first ? like because that would let us have more ingots retained finally because of b ? better for future use. similarly for second one too we can argue the same its better to try using the higher cost aj if thats not possible to craft then go to aj having lower cost , for future benefit .

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

    I was solving this today and my initial idea was the same but i was not sure that this would work since my mind was occupied by the n * m time complexity which would give tle. Nice solution btw.

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

Detailed Video Editorial | English Language

B : https://youtu.be/izeasCQM6Mc

C : https://youtu.be/K9Lj5WFtwXc

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

Can anyone explain me why lcs was not working in problem B I was able to solve but still confused where it could have gone wrong

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

    lcs does not work because as per the question we need to find the longest contiguous substring of b that occurs as a subsequence in a. for example if a="ab" and b="sasb" the lcs is "ab" with length 2 but as we can see it is not useful for us as in our final string there must be a 's' between 'a' and 'b'. the answer string would be "sabsb" with length 5.

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

    Actually you needed to find the longest contiguous substring of b that occurs as a subsequence in a. It can be done using LCS algorithm only, it just need 1 little modification in the else part. Instead of finding max(dp[i — 1][j], dp[i][j — 1]), we can do this

    for (int i = 1; i <= n; i++) 
    {
        for (int j = 1; j <= m; j++) 
        {
            if (a[i - 1] == b[j - 1]) dp[i][j] = 1 + dp[i - 1][j - 1];
            else dp[i][j] = dp[i - 1][j];
        }
    }
    for (int i = 1; i <= m; i++) mx = max(mx, dp[n][i]);
    
    • »
      »
      »
      5 месяцев назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      can you elaborate it aa bit more?i was trying the same thing but i don't know how this works.

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

I don't understand, why not use greedy for values ​​of x <= A in D?

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

I calculated the string using a bruteforce. It seems to be missing a testcase. What is it that I am missing in this: https://codeforces.me/contest/1989/submission/267683386

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

267914972 can anyone please explain why this might be giving a TLE? Is that the priority queue? I used it as a max-heap as I believe I should use maximum possible ingots each time, for the minimum difference in crafting and smelting

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

problem B test case sample can drive you insane they can work with any wrong algorithm you come up with

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

    So LCS is one of the wrong algorithms?

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

      yes, I used LCS earlier and got scammed

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

        Actually you needed to find the longest contiguous substring of b that occurs as a subsequence in a. It can be done using LCS algorithm only, it just need 1 little modification in the else part. Instead of finding max(dp[i — 1][j], dp[i][j — 1]), we can do this

        for (int i = 1; i <= n; i++) 
        {
            for (int j = 1; j <= m; j++) 
            {
                if (a[i - 1] == b[j - 1]) dp[i][j] = 1 + dp[i - 1][j - 1];
                else dp[i][j] = dp[i - 1][j];
            }
        }
        for (int i = 1; i <= m; i++) mx = max(mx, dp[n][i]);
        
        • »
          »
          »
          »
          »
          5 месяцев назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

          I got it.The ordinary LCS cannot tell which string is substring and which is subsequence.

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

can anyone please explain why i'm getting wrong answer on B 267919922

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

    The order of the elements in the string are important by just counting the elements, you are ignoring the order .

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

As usual, BledDest blesses us with high-quality problems!

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

Can someone please help me with D. I can't figure out why this is giving TLE on testcase 5

267937823

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

Are D tests weak? My solution uses memoization with a vector of maps and passes in 2.8 seconds. My solution relies on the fact that if the net costs are very high or very low, then all of the metal is expended quickly. For this reason I think the worst case would be on the order of O(log n sqrt(max) n)? Submission: https://codeforces.me/contest/1989/submission/267939272

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

my solution for question e was this : https://codeforces.me/contest/1989/submission/267952069

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

tried solving B using dp, why doesn't it work?

https://codeforces.me/contest/1989/submission/267759332

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

    If you are using LCS logic,it will not work in this question.

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

    Actually you needed to find the longest contiguous substring of b that occurs as a subsequence in a. It can be done using LCS algorithm only, it just need 1 little modification in the else part. Instead of finding max(dp[i — 1][j], dp[i][j — 1]), we can do this

    for (int i = 1; i <= n; i++) 
    {
        for (int j = 1; j <= m; j++) 
        {
            if (a[i - 1] == b[j - 1]) dp[i][j] = 1 + dp[i - 1][j - 1];
            else dp[i][j] = dp[i - 1][j];
        }
    }
    for (int i = 1; i <= m; i++) mx = max(mx, dp[n][i]);
    
»
5 месяцев назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

267826797 ques b) can anyone why its not giving right output or on which test case it fails

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

I tried to solve Problem C, I am calculating x, y pos & neg in similar way as shown in the editorial. after that i tried greedy approach, i got rid of the for loop and made both x and y equal by doing this.

int temp; // assume x >= y
temp=min(x-y,pos);
y+=temp , pos-=temp;

temp=min(x-y,neg);
x-=temp , neg-=temp;

now we have a simple case where x==y which can be solved easily by doing this

x+=(pos>>1)  , y+=(pos>>1);
x-=(neg>>1)   ,y-=(neg>>1);

if((pos^neg)%2 && (neg%2))
{
   x--;
}
cout<<x<<endl;

EDIT: ACCEPTED

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

For people why LCS is not working for problem b actually you needed to find the longest contiguous substring of b that occurs as a subsequence in a. It can be done using LCS algorithm only, it just need 1 little modification in the else part. Instead of finding max(dp[i — 1][j], dp[i][j — 1]), we can do this

for (int i = 1; i <= n; i++) 
{
    for (int j = 1; j <= m; j++) 
    {
        if (a[i - 1] == b[j - 1]) dp[i][j] = 1 + dp[i - 1][j - 1];
        else dp[i][j] = dp[i - 1][j];
    }
}
for (int i = 1; i <= m; i++) mx = max(mx, dp[n][i]);
»
5 месяцев назад, # |
  Проголосовать: нравится +2 Проголосовать: не нравится

F can be solved by using the well-known Radecki algorithm

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

For problem D i have written same solution as given in tutorial but it is giving TLE on test case 9

267975922 can anyone justify?

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

[resolved]

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

For D, I think I'm doing the same thing that's mentioned in the tutorial but I'm getting TLE. Can someone please help me here? I don't know what's causing the TLE. https://codeforces.me/contest/1989/submission/268040829

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

Can anyone tell me how to do B by graphs?

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

Appreciate the Todd Howard reference in Q4

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

Hey can someone give me a case for which my solution fails My solution — a.size + b.size — longestCommonSubsequence(a,b)

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

// Online C++ compiler to run C++ program online

include <bits/stdc++.h>

using namespace std;

define ll long long

void solve(){ string a,b; cin>>a>>b;

ll n=a.size(); ll m=b.size(); ll i=0,j=0; ll ans=n; vectorvis(n,false); int match=0; while(j<m){ if(i>=n){ i=match; // i++; ans++; j++; }

else if(a[i]!=b[j]){
    i++;
}
else if(a[i]==b[j]&& vis[i]==false){
    match=i;
    vis[i]=true;
    i++;
    j++;
}
else{
    i++;
}

}

cout<<ans<<endl;

}

int main() {

ll t;

cin>>t; while(t--){ solve(); }

return 0;

}

can anyone plz tell where i m getting wrong???

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

// Online C++ compiler to run C++ program online

include <bits/stdc++.h>

using namespace std;

define ll long long

void solve(){ string a,b; cin>>a>>b;

ll n=a.size(); ll m=b.size(); ll i=0,j=0; ll ans=n; vectorvis(n,false); int match=0; while(j<m){ if(i>=n){ i=match; // i++; ans++; j++; }

else if(a[i]!=b[j]){
    i++;
}
else if(a[i]==b[j]&& vis[i]==false){
    match=i;
    vis[i]=true;
    i++;
    j++;
}
else{
    i++;
}

}

cout<<ans<<endl;

}

int main() {

ll t;

cin>>t; while(t--){ solve(); }

return 0;

}

can anyone plz tell me where i m wrong???

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

any one knows why the DP on problem C is wrong
is it not always optimal to take the maximum min at each state ? I tried making a simple dp[n][2] dp[i][0] means to take the first option and extend from the maximum min from dp[i-1] and dp[i][0] means to take the second option and also extend max min from dp[i-1]

can some help why this is wrong ? here is my submission https://codeforces.me/contest/1989/submission/268130928

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

    hey you got the answer? i was using the same approach but so far no luck with dp

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

      no it's not solvable with dp it's not always optimal to only extend the maximum min, sometimes you need to extend a non optimal sub answer to reach the optimal final answer so it's not dp at all I guess. try to think greedy .

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

Can anyone please explain why this Code is not working? I can't find where I have made a mistake. Is my approach wrong?

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

Amazing editorial of D!!!

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

can someone tell why this submission is wrong 268881012 for problem C

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

Was it intentional that O(nlogn) solutions of D Fail or is my implementation just garbage? python code

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

Someone please explain why this solution is taking so long for larger values of c = 1e9, even after optimisation. It is supposed to run in O(max(a_i)*n) time but it's not.

#include <iostream>
#include <vector>
using namespace std;


int main(){
    int n, m;
    cin >> n >> m;
    
    vector<int> a(n+1, 0), b(n+1, 0);
    vector<long long> c(m+1, 0ll);
    for(int i=1; i<=n; i++) cin >> a[i];
    for(int i=1; i<=n; i++) cin >> b[i];
    for(int i=1; i<=m; i++) cin >> c[i];
    
    long long mx = 0ll;
    for(int i=1; i<=m; i++) mx = max(mx, c[i]);

    int mxA = 1e9, best =1e9;
    for(int i=1; i<=n; i++) mxA = max(mxA, a[i]), best = min(best, a[i]-b[i]);
    
    // for all c[i], in  1 to m, if c[i] is greater than max(a_i), make it down to c[i] <= max(a_i)
    vector<long long> dp(mxA+1, 0ll);
    // dp[0] will be used to store the answer
    for(int i=1; i<=m; i++){
        if(c[i] > mxA){
            long long k = (c[i]-mxA)/best;
            dp[0] += 2ll*k;
            c[i] -= k*best;
        }
    }

    // once, all the c[i] have become down to c[i] <= max(a_i), apply dp to maximise exp.
    for(int i=1; i<=mxA; i++){
        for(int j=1; j<=n; j++)
            if(i >= a[j]) dp[i] = max(dp[i], dp[i -(a[j]-b[j])]+2);
    }
    
    // sum all the experiences
    for(int i=1; i<=m; i++) dp[0] += dp[c[i]];
    cout << dp[0] << endl;
    
    return 0;
}
»
4 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

In question C. Can I not do dp here. Like checking for all the possibilities and then taking the most appropriate solution.

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

In my case i did the solution that is from awoo(specifically the first 1), is this considered a bad practice??

Here is the code:

# number of test cases
testCases  = int(input())



i = 1


# loop for iterating the number of test cases
while(testCases >= i):
# coorditnates of the coin (xi, yi)
 x , y = map(int, input().split())



# check if yi is less than or equal to negative two print 'NO' else print 'YES'
 if y <= -2:
  print('NO')
 else:
  print('YES')

 i += 1