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

Автор mitsukiyo, история, 4 месяца назад, По-английски

Scroll directly to the last sentence if you want to avoid spoilers on some 1800-2100 rated problems

Disclaimer: the following post is drafted according to my personal experience, I acknowledge that others might have different paths to improvement and it'd be helpful to provide more perspectives in the comments. Also, I don't know if I'm regurgitating some older posts, but I still think it's helpful to provide a more recent update.

I reached CM after the recent div1+2 round, here's a list of all the algorithms I've used on my past 4 official contests where I've gained the most rating:

Educational Codeforces Round 148 (Rated for Div. 2)

1832A - New Palindrome, 1832C - Contrast Value: none 205576206 205584244

1832B - Maximum Sum: prefix sums 205579825

1832D1 - Red-Blue Operations (Easy Version): (hacked but right idea) greedy, binary search 205597153

1832E - Combinatorics Problem: prefix sums, binomial coefficients 205605946

Performance rating: 1927 (would've been ~2200 if I didn't get hacked)


Codeforces Round 878 (Div. 3)

1840A - Cipher Shifer, 1840B - Binary Cafe, 1840E - Character Blocking: none 208720913 208727427 208781811

1840C - Ski Resort: two pointers 208732221

1840D - Wooden Toy Festival: binary search 208742587

1840G1 - In Search of Truth (Easy Version): sqrt decomposition 208757942

Performance rating: 2183


Codeforces Round 926 (Div. 2)

1929A - Sasha and the Beautiful Array, 1929B - Sasha and the Drawing: none 246536607 246546010

1929C - Sasha and the Casino: greedy 246544088

1929D - Sasha and a Walk in the City: dfs 246557025

1929F - Sasha and the Wedding Binary Search Tree: binomial coefficients 246537238

Performance rating: 2188


EPIC Institute of Technology Round August 2024 (Div. 1 + Div. 2)

2002A - Distanced Coloring, 2002B - Removals Game, 2002C - Black Circles: none 275805098 275811322 275819238

2002D1 - DFS Checker (Easy Version): dfs 275840969 (please excuse me for the horrendous coding style, this was my first time doing any competitive programming in 2 months)

2002E - Cosmic Rays: stacks 275803661 (I used a deque because I couldn't remember whether I needed a stack or a queue)

Performance rating: 2203


So, based on these contests, it seems like that string algorithms, segment trees and "classical" graph algorithms such as BFS, DSU, Dijkstra, etc. are getting phased out around my level, and it's very possible to reach CM or even master without knowing them. Furthermore, only 1 problem out of 21 used any "advanced" algorithm in general, and it was applied shallowly on a 2200 rated problem.

One might argue that the set of contests I've taken part in is a small sample, so let's check out the 10 most recent 2100 rated problems:

Their tags

As we can see — 1 data structure problem (which did not require segment trees), 1 shortest paths problem, and a staggering 4 dfs's, 4 constructives, 4 greedy's. While I didn't encounter any DP problems, it's proven here to be relevant with 3 problems (also, some problems I've solved have the DP tag while I personally used alternative solutions).

This is not to say that classical algorithms are useless (after all, they're at least beautiful for their own sake and still show up sometimes); just that they shouldn't be atop the priority list of div3 and arguably div2 contestants, for the purpose of rating gain. In any way, when you (re)visit topics like segment trees once you have a higher capacity for abstract thinking, you'll probably find out that you understand applications of them more naturally.

Then, what to prioritize in today's meta? Here are a few insights I've personally realized:

Understand simple things deeply

Binary search, greedy, dfs, two pointers, prefix sums... Everyone should be familiar with them. Oftentimes a slight modification of the basic algorithms would already become a ~1900 rated problem. For example, ideas like binary searching for the answer and using DFS to relay information from the subtrees to the ancestor can be the crux to solving problems like 1852A - Ntarsis' Set and 1929D - Sasha and a Walk in the City.

Of course, it's easy to state that you should do this and harder to put it into practice. I've found that it helps to just write down things. Write down pseudocode when you're trying to modify an algorithm. Write down the inbetween "moving parts" when you're trying to combine two algorithms; for example, while doing 1832D1 - Red-Blue Operations (Easy Version) using my approach, write down what the problem is reduced to after the greedy observation, and then figure out that you can use binary search. It's usually more complicated in practice but you'll probably get better intuition regarding what to write down as you tackle harder problems.

Get good at guessing

I guessed the answers to problems A,B,C on my last contest. I don't think I could have proved C in time and would've taken several minutes to prove A or B. This advice is covered in more detail in a YouTube video here. Though, I feel like a secret behind being good at guessing is fast arithmetics and pattern recognition. For example, on 1929C - Sasha and the Casino, I guessed when the answer was -1 quickly by just observing that $$$\frac{1}{2}+\frac{1}{3}+\frac{1}{6}=1$$$ but $$$\frac{1}{2}+\frac{1}{3}+\frac{1}{7}<1$$$, and on 2002A - Distanced Coloring, I guessed the solution in a few seconds by factorizing the answers to the samples in my head. It's possible to guess even high-rated problems like 1762E - Tree Sum (as one of my CM friends did in-contest), but that requires some sort of way to develop intuition about the problem that's hard to cover in text.

Learn some combinatorics

A lot of 2000+ combinatorics problems require nothing but basic binomial coefficient identities, such as 1696E - Placing Jinas, 1832E - Combinatorics Problem, 1929F - Sasha and the Wedding Binary Search Tree. I think that AoPS Alcumus is a solid resource to practice them. Combinatorial ideas also permeate through even early div3 problems such as 1840B - Binary Cafe, so it's essential to get familiar with them early on. rather than be afraid of math.

Constructives

Honestly, I feel like I don't have a lot to say besides to come up with small cases, which is a common advice. Though, a useful remark that I don't see often is that if the answer is ever NO (which should happen in the samples if there's not always a construction), do everything to find out why, because it often has clues as to how to construct a YES. Look at 1852B - Imbalanced Arrays; by just looking at the second test case in the sample, you'd wonder why of all 5 test cases, it's the only one that doesn't work. Trying to come up with properties unique to it in the samples would readily lead to the observation that the two 4's made it bad, and that the frequency of $$$n$$$ in $$$a_i$$$ is important, which should readily lead to the first step in the official solution.

TL;DR learn binary search, but also learn combinatorics and learn to read samples.

  • Проголосовать: нравится
  • +81
  • Проголосовать: не нравится

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

Just guess all the way and then learn some basic data structures. You don't even need segment tree, just learn fenwick and it's enough.

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

    Hey, can you explain me how can I use segment tree to solve this problem epic_aug_round_D2. The problem is about validating the given permutation if it is a valid dfs or not. The authors solution mentions that we can impose some check on each node in the permutation.

    Specifically, For every u, all of its children v satisfies

    $$$[pos_v, pos_v + siz_v-1] \subseteq [pos_u, pos_u + siz_u-1]$$$

    And, we can maintain this check by keeping track of the number of u which violates this condition, and check for each u using sets.

    First of all, how can we do this using sets, and how can we do this using segment tree. I tried thinking a lot, but I could only think of maintaining a segment tree using dfs entry time. So each segment node in the segment tree contains a set/vector containing entry times for each tree node in this segment. And for swapping part, I could do it like replacing the entry time for swapped nodes in the set of their respective segments.

    Then how can I perform verifying this check for each node using this segment tree? This is where I'm getting stuck. Can you help me out, Please.

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

      set: 276417593, Don't overcomplicate the problem using segment

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

        I know its above my level, but all I wanted is to get the idea how it can be applied in this scenario. As I know basics of it so I was interested to see what will be its node structure(i.e. what information about the segment it will store at its node) and how the joint operation would be defined i.e. how the upper level segments will be constructed based on their lower level segments. It really was just out of curiosity and nothing else. At beginner level of segment tree we mostly see sum, max/min type of things, so seeing this problem I got the hint that it can be solved using segment tree and it not going to be obvious to guess the states. That's why I got so curious about it.

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

Auto comment: topic has been updated by mitsukiyo (previous revision, new revision, compare).

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

But they are hard problems man