Serval's blog

By Serval, 23 hours ago, In English
Fun Fact 1
Fun Fact 2
Fun Fact 3
Fun Fact 4
Fun Fact suggested by testers

2085A - Serval and String Theory

Hint 1
Hint 2
Solution
Code (Python)

2085B - Serval and Final MEX

Hint 1
Hint 2
Solution
Another Hint
Another Solution
Code (Python)

2085C - Serval and The Formula

Hint 1
Hint 2
Solution
Code (Python)

2085D - Serval and Kaitenzushi Buffet

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

2085E - Serval and Modulo

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

2085F1 - Serval and Colorful Array (Easy Version)

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

2085F2 - Serval and Colorful Array (Hard Version)

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

»
23 hours ago, # |
  Vote: I like it +50 Vote: I do not like it

Nice contest!

»
23 hours ago, # |
  Vote: I like it +55 Vote: I do not like it

If only Hint 1 was available for D during the contest , good problems overall.

»
23 hours ago, # |
  Vote: I like it +11 Vote: I do not like it

First time ever I do have a feel I can solve problems in Div2D and Div2F1.

Great problem setting, thanks for the contest.

»
23 hours ago, # |
  Vote: I like it 0 Vote: I do not like it

very weird that last div2 contest my rank was 419 and delta was 26... now my rank is lower 454 but delta is 33 ... I was expecting it to be 1 digit or maybe negative.

but I am ok with this... ha ha

  • »
    »
    23 hours ago, # ^ |
      Vote: I like it +11 Vote: I do not like it

    That is basically because this round have 35k registration.

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

    Furthermore, your last div2 (round 1008) was separated from div1, so you weren't ranked with candidate master, that explain an other part of the difference

    • »
      »
      »
      4 hours ago, # ^ |
      Rev. 2   Vote: I like it 0 Vote: I do not like it

      ok, I think I had a very simplistic view of ranking updates ( which was delta proportional to rank in the current contest only ) ... lot more to know for me

»
23 hours ago, # |
  Vote: I like it +6 Vote: I do not like it

hint 1 for problem D feels like a personal attack, I spent quite some time thinking for DP solution lol.

»
23 hours ago, # |
  Vote: I like it +34 Vote: I do not like it

Nice contest, Even more nice editorial. Thanks to the everyone involved.

  • »
    »
    23 hours ago, # ^ |
      Vote: I like it +33 Vote: I do not like it

    yes, this editorial is very well presented, with hints given, which can help someone who wants to upsolve. kudos

»
23 hours ago, # |
  Vote: I like it +23 Vote: I do not like it

You can easily solve D by going backwards in time and doing a regret greedy

  • »
    »
    22 hours ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    Wow, regret greedy? Do you have a minute to explain what that is/provide an associated blog post that explains it? (after a quick search, I did not find any material on the matter)

    • »
      »
      »
      21 hour(s) ago, # ^ |
        Vote: I like it +8 Vote: I do not like it

      A regret greedy is a greedy where you can exchange decisions from the past with more optimal decisions from the present

      In D, you can swap a plate you took earlier for a more delicious plate now

    • »
      »
      »
      17 hours ago, # ^ |
        Vote: I like it +12 Vote: I do not like it

      I think the idea of regret greedy is that you don't have to take the optimal decision just yet, but later when it is not longer possible to postpone you will have all of the information to take a more optimal decision about the past/present. I don't know if that's what he meant but I also thought of this problem in a similar way. IMO you could also say that this problem resembles a job scheduling problem.

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

    wow, I learn a new term today called "regret greedy"

  • »
    »
    8 hours ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    Can you share a bit about the pattern of regret greedy, what "intuition" drive you to the regret greedy. Thank so much.

»
23 hours ago, # |
Rev. 2   Vote: I like it +3 Vote: I do not like it

Serval please fix problem C's first hint !

thanks in advance!

UPD: Fixed!

»
23 hours ago, # |
  Vote: I like it +7 Vote: I do not like it

Finally hit CM! Very enjoyable round imo (definitely not biased), peak problems.

»
23 hours ago, # |
  Vote: I like it 0 Vote: I do not like it

A nice contest with fast editorial!

»
22 hours ago, # |
  Vote: I like it 0 Vote: I do not like it

Good contest with fast Editorial. The problems are interesting will try them all.

»
22 hours ago, # |
Rev. 2   Vote: I like it +3 Vote: I do not like it

Solution to the C is out of the box, wow. i was able to get upto (x + K ) and (y + k) = 0. I think hard after this. but that was the wrong direction.

  • »
    »
    21 hour(s) ago, # ^ |
      Vote: I like it +1 Vote: I do not like it

    Yeah, same here! At first, I was trying to guess each bit of $$$k$$$ which just made the solution way more complicated than it needed to be. But after refining it, it finally got accepted! 311918873

    • »
      »
      »
      68 minutes ago, # ^ |
      Rev. 2   Vote: I like it 0 Vote: I do not like it

      I tried similar thing my solution is stuck on some 300th tc of 2nd tc. if it is not too much trouble can you please take a look at my code.


      #include<bits/stdc++.h> typedef long long ll; using namespace std; ll posFind(ll x, ll lsb) { while (lsb > 1 && (x&(lsb >> 1))) lsb>>=1; return lsb; } int main() { cin.tie(0); ll t; cin >> t; while (t--) { ll x, y; cin >> x >> y; ll ans = 0; if (x == y) { cout << -1 << endl; continue; } while (x&y) { ll a = x&y; ll lsb = (a & (a-1)) ^ a; ll lx = posFind(x, lsb), ly = posFind(y, lsb); ll ch = min(lx, ly); ans += ch; x += ch, y += ch; } cout << ans << endl; } return 0; }
  • »
    »
    14 hours ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    same here lol

»
22 hours ago, # |
  Vote: I like it 0 Vote: I do not like it

How is this solution for B incorrect?
I am trying to break the array into two parts through mid, and I am checking for both parts. Whichever contains at least one 0, I apply the operation once on it.
Then, I finally apply the operation on the leftover two elements (if the operations were applied on both parts, then we are left with two elements at the end, and they are not 0).

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

int main() {
    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        int a[n + 1] = {0};
        for (int i = 1; i <= n; i++) cin >> a[i];

        int mid = n / 2;
        bool left = false, right = false;

        for (int i = 1; i <= mid; i++) {
            if (a[i] == 0) {
                left = true;
                break;
            }
        }

        for (int i = mid + 1; i <= n; i++) {
            if (a[i] == 0) {
                right = true;
                break;
            }
        }

        if (left && right) {
            cout << 3 << endl;
            cout << 1 << " " << mid << endl;
            cout << 2 << " " << n - mid + 1 << endl;
            cout << 1 << " " << 2 << endl;
        } else if (left && !right) {
            cout << 2 << endl;
            cout << 1 << " " << mid << endl;
            cout << 1 << " " << n - mid + 1 << endl;
        } else if (!left && right) {
            cout << 2 << endl;
            cout << mid + 1 << " " << n << endl;
            cout << 1 << " " << n - mid + 1 << endl;
        } else {
            cout << 1 << endl;
            cout << 1 << " " << n << endl;
        }
    }
    return 0;
}
  • »
    »
    22 hours ago, # ^ |
    Rev. 2   Vote: I like it 0 Vote: I do not like it

    your code is not correct. for this input: n= 5, array = 1 2 3 4 0

    output of your code: k = 2, l = 3 and r= 5, l = 1 and r = 4

    after first operation length of your array becomes 3. but in 2nd operation how can you remove from 1 to 4?

»
22 hours ago, # |
  Vote: I like it 0 Vote: I do not like it

Great contest, really enjoyed the problems.

»
22 hours ago, # |
  Vote: I like it 0 Vote: I do not like it

can anyone explain d in dp format

  • »
    »
    17 hours ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    D is a classic knapsack problem(Allowed maximum k operation to obtain maximum/minimum),In D you can think like this,you are gonna to choose i dishes and finish it,so the problem reduce to do i operation to obtain maximum d[i],sound like a knapsack problem right?But the classic knapsack problem got a O(n*k) time complexity in this problem k up to n so the worst case will become O(n^2) which will tle but knapsack problem got a effiency way is to use datastructure(HEAP),heap is a tree structure which root is always minimum/maximum(depend on which heap you use),so the idea is when you loop from right to left(from n-k to 1)(1-based) if you can freely choose a new element then choose it because this always increase your total d[i],but if you can't freely choose a element then you try to exchange the current d[i] with the deliciousness you had choose,because the previous deliciousness you had choose spent k+1 minute and the current d[i] also spent k+1 minute then you can directly exchange.311940708

»
22 hours ago, # |
  Vote: I like it 0 Vote: I do not like it

i think E was much much easier than D and C, i did not even open it because of D

»
22 hours ago, # |
  Vote: I like it 0 Vote: I do not like it

As frustrated as I am for not being able to solve Problem C, I am truly impressed and in awe by its solution. The feeling that yes, this is so very much interesting. Thank you for the contest and the concise solutions and this fast, well-prepared editorial.

»
22 hours ago, # |
  Vote: I like it 0 Vote: I do not like it

Can someone explain D to me? that % one is not very intuitive

  • »
    »
    11 hours ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    Let i = n-j(k+1)+1. Then we have n-i+1 = j(k+1), which is divided by k+1. i here is the position where we should determine which plate to take.

»
21 hour(s) ago, # |
  Vote: I like it 0 Vote: I do not like it

One of the best contests in a while , not many prerequisites and just logical stuff . And also the solutions are surprisingly short :pray:

»
21 hour(s) ago, # |
  Vote: I like it 0 Vote: I do not like it

serval my glorious king im honored to give a contest written by you

»
21 hour(s) ago, # |
  Vote: I like it 0 Vote: I do not like it

in problem A,can't i just swap s[0] with something smaller than s[0] from the string,or swap s[n-1] with something greater than s[n-1] when s[0]==s[n-1] and if k>0? like abba and k=1 so abab and k=0 thus abab is a universal string. can anyone point out the mistakes in my logic? and if s[0]>s[n-1] we will just swap s[0] with s[n-1] and need 1 operation and no operations are needed if s[0]<s[n-1]

  • »
    »
    20 hours ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    The logic is correct; I don't see the issue.

    • »
      »
      »
      20 hours ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      but it gives wrong answer on testcase 2 ;(

      • »
        »
        »
        »
        20 hours ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        If k>0 and the string does not consist of the same character, then the answer is always YES.

        • »
          »
          »
          »
          »
          20 hours ago, # ^ |
            Vote: I like it 0 Vote: I do not like it

          yes, also if the string is abcd and k=0 then the answer will also be YES right?because it is already universal. and if its dbca and k=1 i will just simply interchange s[0] with s[n-1] -abcd,so i dont exactly find any mistakes in my code.

          • »
            »
            »
            »
            »
            »
            18 hours ago, # ^ |
            Rev. 2   Vote: I like it 0 Vote: I do not like it

            Answer is YES unless: k=0 and r is not universal, or k>0 and r has only one distinct character

          • »
            »
            »
            »
            »
            »
            16 hours ago, # ^ |
              Vote: I like it 0 Vote: I do not like it

            thats how I coded my solution look at my sol

             int n, k;
                cin >> n >> k;
                string s;
                cin >> s;
                string t = s;
                reverse(all(t));
                map<char,int> mp;
                rep(i,0,n) mp[s[i]]++;
                if(mp.size()>1 && k){
                    yes();
                    return;
                }
                if (s < t) {
                    yes();
                    return;
                }
                else if(k==0){
                    no();
                    return;
                }
                else{
                    no();
                    return;
                }
            
            • »
              »
              »
              »
              »
              »
              »
              6 hours ago, # ^ |
              Rev. 4   Vote: I like it 0 Vote: I do not like it

              can you find an edge case for my solution,its showing wrong answer on test case 2

              int n;cin>>n;
                 int k;cin>>k;
                 string s;cin>>s;
                 if(n==1)cout<<"NO"<<endl;
                 else{
                  if(s[0]==s[n-1]){
                      for(i=1;i<n-1;i++){
                          if(s[i]>s[0] || s[i]<s[0]){
                              n=-1;
                              break;
                          //swap s[0] with something smaller than s[0]
                          //or swap s[n-1] with something bigger than s[n-1]
                          }
                      }
                      if(n==-1 && k>0)cout<<"YES"<<endl; 
                      else cout<<"NO"<<endl;
                  }
                  else if(s[0]<s[n-1])cout<<"YES"<<endl;
                  else if(s[0]>s[n-1]){
                      if(k>0)cout<<"YES"<<endl;
                      else cout<<"NO"<<endl;
                  }
                 }
              
              • »
                »
                »
                »
                »
                »
                »
                »
                3 hours ago, # ^ |
                  Vote: I like it 0 Vote: I do not like it

                Your code fails for the following test case:

                1
                4 0
                abca
                
»
20 hours ago, # |
  Vote: I like it 0 Vote: I do not like it

Solution for C says "sufficient large" instead of "sufficiently large"

»
20 hours ago, # |
Rev. 2   Vote: I like it -18 Vote: I do not like it

I absolutely hate these kinds of editorials, where the solution to a problem is written in 4 lines like — oh we can do this for the solution, then do that, then do this greedy approach which we won't explain how it is correct, and then finally find answer with some random data structure which we won't bother to implement. You might as well don't write the editorial please, it will make no difference.

You guys need to understand that a person who comes to the editorial, is expecting a detailed solution with good explanation, so that he/she can learn the idea behind it and use in future problems, and not a 4 line paragraph where half of the things are just written without any proofs or anything. Random people posting explanation in discussion thread are far better than these stupid editorials.

  • »
    »
    4 hours ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    I feel you and I will suggest doing some competitions on codechef, they have really detailed editorials

    also try to follow some YouTubers who analyze questions after the contest as they cover lower rated problems quite well. and then you can try to read editorials

    That is what I do when I am not able to make sense of editorial, or I comment on the editorial post asking people for help and questions which are solved by large number of people generally get some explanation. so we can help each other and write different explanations in the comments

»
20 hours ago, # |
  Vote: I like it +3 Vote: I do not like it

Can someone explain C again pls ?

  • »
    »
    19 hours ago, # ^ |
      Vote: I like it +6 Vote: I do not like it

    $$$a$$$ ^ $$$b$$$ = $$$a$$$ + $$$b$$$ - $$$2$$$ * ($$$a$$$ & $$$b$$$) so the equation is $$$a$$$ + $$$b$$$ = $$$a$$$ + $$$b$$$ - $$$2$$$ * ($$$a$$$ & $$$b$$$) That means that ($$$a$$$ & $$$b$$$) = $$$0$$$ — ($$$x$$$ + $$$k$$$) & ($$$y$$$ + $$$k$$$) = $$$0$$$

    We observe that a power of two is represented like that $$$10000...$$$ and any number before it doesn't have the most significant bit on so their ANDing will always be $$$0$$$. We want to add $$$k$$$ to both numbers such that the greater of them becomes a power of $$$2$$$ and the other one becomes less than it.

    If both are equal then their ANDing after addition will never be 0. Otherwise, we can find the first $$$n$$$ such that $$$2^n$$$ >= $$$max(x, y)$$$ and make $$$k$$$ equal to $$$2^n$$$ - $$$max(x, y)$$$

    • »
      »
      »
      8 hours ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      Great explanation, thanks.

      Repeating his explanation, we want the two final numbers to have bitwise AND AS 0. So, one way is, make one number as a power of 2, and the other number somewhat less than the first. Thus, they will have no set bit common.

      Method: Add just enough to the greater of the two (max(x, y)), to make it a power of two. Since the two numebrs are different, the smaller number will also be smaller after adding k.

      Code: 312044416

»
19 hours ago, # |
  Vote: I like it +3 Vote: I do not like it

E was too much beautiful for proving me so dumb :(

»
18 hours ago, # |
  Vote: I like it 0 Vote: I do not like it

Funnily enough I solved F1 without realizing you need $$$k/2$$$... and reading that hint was enough to solve F2. The data structure was not that heavy, you need a multiset for maintaining the smallest $$$k/2$$$ elements and another one for maintaining the remaining $$$k-k/2$$$.

»
18 hours ago, # |
  Vote: I like it 0 Vote: I do not like it

check(0xc0ffee) Lol nice way to check for a random large mod in Solution for E

»
18 hours ago, # |
  Vote: I like it 0 Vote: I do not like it

problem D https://codeforces.me/contest/2085/submission/311937721

can someone explain to me why this code fails? tnx.

»
17 hours ago, # |
  Vote: I like it 0 Vote: I do not like it

pretty good problem C , it has a pretty nice consructive solution https://codeforces.me/contest/2085/submission/311939672

»
16 hours ago, # |
  Vote: I like it 0 Vote: I do not like it

Problem A with unclear meaning.

»
15 hours ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

Loved solving (with a different approach) problem A! Video editorial link : https://youtu.be/yHD1pi2l2G0?si=s2hX91_CyHbdMn_-

»
15 hours ago, # |
  Vote: I like it 0 Vote: I do not like it

surprising problem C solution, i was not expecting O(t).

I was trying to do bitmasks but failed

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

God editorial

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

2085D - Serval and Kaitenzushi Buffet Could someone please help me understanding what is wrong with my approach or code.

Approach:

While processing the time(0-index based) from n — 2(second last) to 0, I am trying to find out if I take the plate at time = i, then what is maximum sum of deliciousness of plates I can take at time > i, such that taking and consuming those plates (k + 1 for each plate) takes time <= n — 1 — (i + k), as this is the time left when I take plate i -> i + k time consumed. For that i am using a segment tree, in which I am storing for time = 0 to n, the (maximum sum of deliciousness, time) for each range processed by far.

Code:

#include <iostream>
#include <vector>

using namespace std;

struct Node {
    long long val;
    int len;
    Node () : val(0), len(0) {};
    Node (const long long& val, const int& len) : val(val), len(len) {};
    void output () {
        cout << val << ' ' << len << ' ';
    }
    const bool operator< (const Node& oth) const {
        return val == oth.val ? len > oth.len : val < oth.val;
    }
};

template <typename T>
struct SegTree {
    int n;
    vector<T> segTree;

    SegTree (const int& n) : n(n), segTree(n) {}

    T comp (const T& a, const T& b) {
        return max(a, b);
    }

    void update (int node, int l1, int r1, T& val, int tl, int tr) {
        if (l1 > r1) return;
        if (l1 == tl && r1 == tr) {
            segTree[node] = max(segTree[node], val);
            return;
        }
        int m = tl + (tr - tl) / 2, n1 = node + 1, n2 = node + 2 * (m + 1 - tl);
        update(n1, l1, min(r1, m), val, tl, m);
        update(n2, max(l1, m + 1), r1, val, m + 1, tr);
        segTree[node] = comp(segTree[n1], segTree[n2]);
    }

    T query (int node, int l1, int r1, int tl, int tr) {
        if (l1 > r1) return Node();
        if (l1 == tl && r1 == tr) return segTree[node];
        int m = tl + (tr - tl) / 2, n1 = node + 1, n2 = node + 2 * (m + 1 - tl);
        return comp(query(n1, l1, min(r1, m), tl, m), query(n2, max(l1, m + 1), r1, m + 1, tr));
    }

    void output () {
        for (int i = 0; i < n; i++) cout << segTree[i].val << ' '; // cout << segTree[i].output() << ' ';
        cout << "\n";
    }
};

int main () {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    short t;
    cin >> t;
    for (short tc = 1; tc <= t; tc++) {
        int n, m, k;
        cin >> n >> k;
        int d[n];
        m = 2 * (n + 1) - 1;
        SegTree<Node> segTree(m);
        for (int i = 0; i < n; i++) cin >> d[i];
        for (int i = n - 2; i >= 0; i--) {
            if (i + k < n) {
                int j1 = n - 1 - i - k, j2 = n - 1 - i - 2 * k - 1;
                Node val1 = segTree.query(0, 0, j1, 0, n), val2;
                if (i + 2 * k + 1 < n) val2 = segTree.query(0, 0, j2, 0, n);
                val1.val += d[i];
                val1.len += k + 1;
                segTree.update(0, val1.len, val1.len, val1, 0, n);
                if (i + 2 * k + 1 < n) {
                    val2.val += d[i];
                    val2.len += k + 1;
                    segTree.update(0, val2.len, val2.len, val2, 0, n);
                }
            }
        }
        cout << segTree.query(0, 0, n, 0, n).val << "\n";
    }

    return 0;
}

Submission link: 311909974

Thanks in advance.

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

the editorial with hints are way better than others

»
8 hours ago, # |
  Vote: I like it +5 Vote: I do not like it

Why account named AnotherAccount was banned?

»
4 hours ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

Does any $$$O(NK)$$$ solution for D exist? I have been thinking a lot on how to solve it and trying to see if anyone does to solve it, but it's either $$$O(N^2/K)$$$ or $$$O(N^2)$$$ (both of which I have did) or $$$O(N\log{N})$$$ (intended sol)

Why