wsyear's blog

By wsyear, 6 hours ago, In English

2048A - Kevin and Combination Lock

Author: Little09

Hint 1
Tutorial

2048B - Kevin and Permutation

Author: wsyear

Hint 1
Tutorial

2048C - Kevin and Binary Strings

Author: Little09

Hint 1
Hint 2
Hint 3
Tutorial

2048D - Kevin and Competition Memories

Author: cmk666

Hint 1
Hint 2
Hint 3
Tutorial

2048E - Kevin and Bipartite Graph

Author: Little09

Hint 1
Tutorial

2048F - Kevin and Math Class

Author: wsyear

Hint 1
Hint 2
Tutorial

2048G - Kevin and Matrices

Author: cmk666

Hint 1
Hint 2
Hint 3
Hint 4
Tutorial

2048H - Kevin and Strange Operation

Author: JoesSR

Hint 1
Hint 2
Hint 3
Tutorial

2048I1 - Kevin and Puzzle (Easy Version)

Author: Little09

Hint 1
Tutorial

2048I2 - Kevin and Puzzle (Hard Version)

Author: Little09

Hint 1
Hint 2
Hint 3
Hint 4
Tutorial
  • Vote: I like it
  • +46
  • Vote: I do not like it

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

first

I was one $$$=$$$ sign off from getting $$$E$$$ lol

  • »
    »
    110 minutes ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    Haha me too. I wrote > 2*n instead of >= 2*n lol. Now first time losing rating

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

I think the $$$O(n)$$$ solution for C is quite interesting. Why not split it into a C2?

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

    I agree

  • »
    »
    5 hours ago, # ^ |
      Vote: I like it -31 Vote: I do not like it
    import java.util.*;
    
    public class Main {
        public static void main(String __[]) {
            var sc = new Scanner(System.in);
            var t = sc.nextInt();
            sc.nextLine();
            while (t-- > 0) {
                var s = sc.nextLine();
                var n = s.length();
                var a2 = new ArrayList<ArrayList<Integer>>();
    
                for (var i = n - 1; i >= 0; i--) {
                    var a1 = new ArrayList<Integer>();
                    a1.add(i);
                    a1.add(i);
                    for (var j = i; j >= 0; j--) {
    
                        // MAIN LOGIC
                        if (s.charAt(n - 1 - i + j) != s.charAt(j)) {
    
                            a1.add(n - 1 - i + j);
                            a1.set(1, j);
    
                        }
    
                    }
                    if (a1.size() > 2) a2.add((ArrayList) a1.clone());
                }
    
                a2.sort((x, y) -> {
                    var xs = x.size();
                    var ys = y.size();
    
                    for (var i = 1; i <= Math.min(xs, ys) - 2; i++) {
                        if (x.get(xs - i) != y.get(ys - i))
                            return x.get(xs - i) - y.get(ys - i);
                    }
    
                    return ys - xs;
                });
    
                if (a2.size() != 0)
                    System.out.println("1 " + n + " " + (a2.get(0).get(1) + 1)
                                       + " " + (a2.get(0).get(0) + 1));
                else System.out.println("1 " + n + " 1 1");
            }
        }
    }
    

    Can anyone please guess the error because of which my code is giving wrong answer on the 7th test case.

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

    I was trying to solve C by explicitly taking XOR from numbers (i.e. binary transformed into decimal) and obviously ran out of memory. And then I came to the $$$O(n)$$$ solution.

    (edited)

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

      bro skipped a step from taking the xor of numbers of 5000 digits to finding the optimal solution

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

    Lol I directly coded the O(n) solution :D Slight observation but I was able to get that correct in one go.

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

First time ever i solve 5 problems in a div2, i think D is very cool, and i kinda guessed E but good contest overall

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

great contest and tutorial :)

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

Can anyone explain why my D Solution is too slow?

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

    O(m^2) solution is going to give you TLE as m<=3e5

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

      Thanks for pointing that out. Got tunnel visioned. Later I got this accpeted Here

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

great contest tho I find it wired that F requires such complex data structure (probably it isn't wired and I just lack experience)

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

    It's not complicated structure for F.

  • »
    »
    115 minutes ago, # ^ |
    Rev. 2   Vote: I like it +7 Vote: I do not like it

    Honestly a min Cartesian Tree is just a fancy way of refering to the classic problem of finding for each element its first lower neighbours on the left/right.

    Now you can say that each element is the node corresponding to an interval, and all you need to add is to compute the two childs in the tree (which corresponds to the interval splitted by the minimum value), which requires a bit of thinking but no complicated code.

    Finally to manage the DP in the tree you can do simply dfs using the indices of intervals and never explicitly construct the tree, like you would do in a divide and conquer approach.

    All in all it might be a complex idea but it can be implemented easily (you can check my submission if you'd like (which is $$$O(nlog^2)$$$ should you wonder))

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

Special Thanks to cmk666 for the nice problem 2048D - Kevin and Competition Memories

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

one more div2 contest where i can't solve more than 3 questions.

how should i practice to solve question D in div 2 contests? thanks in advance

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

Anyone tried solving E with below approach.

Each edge can be represented as ordered pair ( i , j ) . where 'i' belongs to left side, and 'j' belongs to right side.

Now, we have total of 2 * n * m such ordered pairs. each of these edge can be actually convert into a vertex. since our graph is bipartite, after we travel one of our edge, next edge direction will be opposite ( if we travel current edge from left to right, next edge we must travel right to left )

=> if I am going from (i,j1) to (i,j2) , i will try to give available color to (i,j2) and then I will keep 'j2' constant and try to find some valid 'i' which is not yet colored and try to color it.

Now start DFS from (1,1) , and if its odd iteration of the we will go from left to right, if it is even iteration, we will go from right to left.

When we go from left to right , we will keep 'i' constant and loop over all the 'j' in the ordered pair ( i , j ) .

When we go from right to left, we will keep 'j' constant and loop over all the 'i'.

We will try to basically color this graph of 2 * n * m vertices,,, with 'n' colors. I tried this approach, but don't know, why does it fail ?

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

E made me sad.

»
5 hours ago, # |
  Vote: I like it -26 Vote: I do not like it
import java.util.*;

public class Main {
    public static void main(String __[]) {
        var sc = new Scanner(System.in);
        var t = sc.nextInt();
        sc.nextLine();
        while (t-- > 0) {
            var s = sc.nextLine();
            var n = s.length();
            var a2 = new ArrayList<ArrayList<Integer>>();

            for (var i = n - 1; i >= 0; i--) {
                var a1 = new ArrayList<Integer>();
                a1.add(i);
                a1.add(i);
                for (var j = i; j >= 0; j--) {

                    // MAIN LOGIC
                    if (s.charAt(n - 1 - i + j) != s.charAt(j)) {

                        a1.add(n - 1 - i + j);
                        a1.set(1, j);

                    }

                }
                if (a1.size() > 2) a2.add((ArrayList) a1.clone());
            }

            a2.sort((x, y) -> {
                var xs = x.size();
                var ys = y.size();

                for (var i = 1; i <= Math.min(xs, ys) - 2; i++) {
                    if (x.get(xs - i) != y.get(ys - i))
                        return x.get(xs - i) - y.get(ys - i);
                }

                return ys - xs;
            });

            if (a2.size() != 0)
                System.out.println("1 " + n + " " + (a2.get(0).get(1) + 1)
                                   + " " + (a2.get(0).get(0) + 1));
            else System.out.println("1 " + n + " 1 1");
        }
    }
}

Can anyone please guess the error because of which my code is giving wrong answer on the 7th test case.

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

G is a nice one! ❤️

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

For F, the constraints don't cut the $$$n \cdot \log^2(a)$$$ solution, but also make it harder for people who are careful.

I spent extra time to optimize out a $$$\log(a)$$$ factor just like the editorial because $$$n \cdot \log^2(a) \approx 8 \cdot 10^8$$$.

If instead the time limit was greater or $$$a = 10^9 \implies n \cdot \log^2(a) \approx 2 \cdot 10^8$$$, I would definitely go for this solution and not waste time. Since I optimized, I failed to finish F by a few minutes.

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

Was curious about F's solution and heard for the first time about min cartesian tree!! Anyone have any good resources to learn more about it?

»
4 hours ago, # |
  Vote: I like it -6 Vote: I do not like it

can someone please help me with this solution. It fails for tc5

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using db = long double; // or double if tight TL
using str = string;

using pi = pair<int,int>;
#define mp make_pair
#define f first
#define s second

#define tcT template<class T
tcT> using v = vector<T>;
tcT, size_t SZ> using AR = array<T,SZ>;
using vi = v<int>;
using vc = v<char>;
using vs = v<string>;
using vb = v<bool>;
using vll = v<long long>;
using vpi = v<pi>;

#define sz(x) int((x).size())
#define all(x) begin(x), end(x)
#define sor(x) sort(all(x))
#define rsz resize
#define pb push_back
#define ft front()
#define bk back()

#define rep(i,a,b) for (int i = (a); i < (int)(b); ++i)
#define repr(i,a,b) for (int i = (b)-1; i >= (a); --i)
#define each(x,a) for (auto& x: a)

const int MOD = 1e9+7;
const db PI = acos((db)-1);

tcT> bool ckmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; } // set a = min(a,b)
tcT> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; } // set a = max(a,b)

// inline void dbg(T x) { cerr << x << endl; }

bool cmp(pair<int, int> p1, pair<int, int> p2) {
    return p1.second < p2.second;
}


bitset<32> to_bitset(string s) {
    auto binary = [](char c) { return c == '0' || c == '1'; };
    auto not_binary = [binary](char c) { return !binary(c); };

    s.erase(std::remove_if(begin(s), end(s), not_binary), end(s));

    return std::bitset<32>(s);
}

string to_string(std::bitset<32> bs) {
    return bs.to_string();
}
void solve(int T) {
    cin >> T;
    while (T--) {
        string s; cin >> s;
        int first = -1;
        rep(i,0,s.size()) {
            if (s[i] == '0') {
                first = i;
                break;
            }
        }
        if (first == -1) {
            cout << 1 << " "<< 1 << " " << 1 << " " << s.size() << endl;
        }
        else {
            int req = s.size() - first;
            string subs = "";
            int l = 0, r = req-1;
            int ansl = l, ansr = l;
            string ansres = "";
            while (r < s.size()) {
                subs = s.substr(l, req);
                auto res = to_string(to_bitset(s)^to_bitset(subs));
                if (res > ansres) {
                    ansres = res;
                    ansl = l+1, ansr = r+1;
                }
                r++; l++;
            }
            cout << 1<<" "<<s.size()<<" "<<ansl << " " << ansr << endl;
        }
    }
}
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int T = 1;
    solve(T);
    return 0;
}

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

    Just replace std::bitset<32> with std::bitset<5007> and the solution passes: 297364634. In the problem, the string length can be up 5000, so the bitset should be capable to store at least 5000 bits.

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

Why is this code for D failing?


int n, m; cin >> n >> m; int me; cin >> me; vector<int>participants, problems, solved; // only participants with rating greater than mine matter for (int i = 0; i + 1 < n; i++){ int num; cin >> num; if (num > me) participants.push_back(num); } // same thing for problems for (int i = 0; i < m; i++){ int num; cin >> num; if (num > me) problems.push_back(num); } sort(participants.begin(), participants.end()); sort(problems.begin(), problems.end()); // computing how many people solve each problem for (int problem : problems){ int first = lower_bound(participants.begin(), participants.end(), problem) - participants.begin(); solved.push_back(participants.size() - first); } sort(solved.begin(), solved.end()); for (int k = 1; k <= m; k++){ int ans = 0; for (int i = k; i <= solved.size(); i += k) ans += solved[i - 1] + 1; cout << ans << " \n"[k == m]; }
  • »
    »
    2 hours ago, # ^ |
    Rev. 2   Vote: I like it 0 Vote: I do not like it

    I had a similar implementation which worked : 297364236 I dont think you can ignore problems with lower difficulty than Kevin's skill since you can use them to "pad" contests

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

      bro im gonna be honest i dont even know what am im doing, could you explain what the greedy algorithm the editorial describes is doing ?

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

For E, I found this paper which solves a slightly more general problem of coloring a complete bipartite graph into the minimum number of colors such that each color is a forest.

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

Can someone please help me out where I am going wrong with C: my submission

I get that the first substring will be the entire string, and the second substring will be of the length = length of complete string — position of first 0 from left. But since we only have to find out which such substring gives the maximum XOR, I take a different parameter called 'ans' in my solution and I claim that the substring which gives the higher 'ans' will also give the higher XOR value.

Here is how I am constructing 'ans': I am comparing the portion of two strings which is to be XOR'ed. Starting from the most significant bit, if the corresponding bit in both the strings are 0 and 1 respectively, I am incrementing ans by a larger value (and decrementing if the bits are 1 and 1 respectively since that will decrease XOR value). As I move from left to right, The value with which I increment/decrement ans decreases (since the right bits will have less contribution to the XOR value than the left bits). The substring which gives the maximum 'ans' value will also give me the maximum XOR value. But I am getting wrong answer on test case 2 itself and I am unable to figure out where I am going wrong! Please help

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

    Maybe my implementation can help you:


    string s; int n; cin >> s; n = s.size(); bool hasZero = false; for (int i = 0; i < n; i++) if (s[i] == '0') { hasZero = true; break; } if (!hasZero) { cout << 1 << " " << n << " " << 1 << " " << 1 << endl; return; } int first_zero = 0; for (int i = 0; i < n; i++) if (s[i] == '0') { first_zero = i; break; } int best_l = 0; int sz = n - first_zero; for (int l = 0; l <= n - sz; l++) for (int i = 0; i < sz; i++) { if (s[first_zero + i] == '1') { // If at this position of the string we have a 1 if (s[l + i] == '1' && s[best_l + i] == '0') // If the current substring has a 1 and my current answer has a 0, the current substring is worse and should not be processed break; if (s[l + i] == '0' && s[best_l + i] == '1') { // If the current substring has a 0 and the current answer has a 1 I found a better answer best_l = l; break; } } else { // if the original string has a '0' if (s[l + i] == '0' && s[best_l + i] == '1') // if the current substring has a 0 and the answer has 1 then this is worse and should not be processed break; if (s[l + i] == '1' && s[best_l + i] == '0') { // if the current substring has a 1 and the answer has a 0 i found a better answer best_l = l; break; } } } cout << 1 << " " << n << " " << best_l + 1 << " " << best_l + sz << endl;
    • »
      »
      »
      2 hours ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      Thanks for your code, I completely understood it. However, I still haven't understood what is wrong in my implementation.

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

        I think your ans logic is flawed, say you have two candidates for strings, the first one has a better most significant bit and the other one has a worse most significant bit but every other bit is better in the second one. Maybe the way your ans is incremented makes the sum of the second one better than the first one if that makes sense

        • »
          »
          »
          »
          »
          115 minutes ago, # ^ |
            Vote: I like it 0 Vote: I do not like it

          Ahh now I get it! I have been trying to figure out a flaw in my logic since the last 4 hours, only to find out it was this trivial :')

          Thank you very much for pointing this out!

»
106 minutes ago, # |
  Vote: I like it 0 Vote: I do not like it

I hate the fact, that I was debugging F for 40 minutes, because I was getting RTEs on test 3. There was some stupid stack overflow; the recursion was returning a big static object (488 bytes), and after changing it to return an 8 byte pointer, it started working; however, my memory usage was under 350MB, so it should have passed initially.