The Journey with Longest SubRoutine

Note: This is an AI-translated version (with minor edits) of my Chinese reflection of our team. The original version is here. Thank you Sonnet 3.7 for the powerful translation and Cursor which allows me to make translation to the markdown file directly.

On April 18, 2024, our team (named Longest SubRoutine) representing the University of Wisconsin-Madison (UWM) achieved 8th place and a silver medal at the 46th ICPC World Finals. This article shares the story behind our three-year journey, from team formation to the final competition, along with some personal reflections. I hope to preserve these memories for myself and my teammates, and perhaps these experiences will resonate with others who are also competing in programming contests.

Team Composition

Our team has been evolving for nearly 3 years since its inception. At the time of formation, the three members were:

  • RobeZH, that’s me, in my final year of undergraduate studies at UWM, majoring in CS, with a Codeforces rating of 2600-2700.
  • Subconscious (Sub for short), who completed his CS undergraduate degree at Zhejiang University and was a member of the Legilimens team there. He was in his first year of a master’s program at UWM, with an impressive Codeforces rating of around 3100 at the time.
  • LUL____SEPLED1305 (Nitit), a sophomore undergraduate at UWM majoring in mathematics, with a Codeforces rating of 2300-2400.
Team composition

Pre-formation

In September 2020, after completing my junior year at UWM, I decided to take a gap year for a research internship at ByteDance. The following May, during a weekend when I was participating in an individual offline competition organized by Metabit, my colleague at ByteDance, fsy, mentioned that Subconscious from Zhejiang University would be coming to UWM for his master’s degree. I had heard about the strength of Sub’s team Legilimens at Zhejiang University, and their teammate chenjb was well-known in ICPC circles across multiple regions and had been my online friend for many years. I was excited after looking up Sub’s CF profile (his rating was already around 2700 at that time), and fsy pointed out that Sub was sitting at a nearby table. This led to the following conversation:

"Are you Subconscious from Zhejiang University?"
"Yes"
"Let's go to the World Finals and win a medal together?"

Everyone present laughed. No one could have imagined that my excited remark would become reality after many challenges. However, even that was a casual remark, knowing about Sub’s arrival gave me hope: perhaps we could achieve something significant. Later that summer, we registered for the Nowcoder Multi-University Training Contest and practiced together on weekends to build our teamwork, continuing until the fall semester began.

In 2020, a Thai student with strong mathematical abilities, Nitit, came to UWM. In October 2021, Nitit became my teammate for a previous final. Through multiple training sessions, I recognized Nitit’s exceptional observational and thinking abilities. Since my coding skills exceeded my problem-solving abilities, I thought Nitit would be an excellent third member to balance our team. After discussing this with Sub, who agreed it was a good idea, I began persuading Nitit to join us. Initially, Nitit was hesitant due to his heavy course load and concerns about being a burden of the team, but after my persistent persuasion and planned training arrangements, he fortunately agreed to join our team.

A fragment of persuading Nitit to join the team

So in November 2021, after Nitit agreed to join, our team was complete. When training with Sub, I had named our team “SubRoutine” based on the prefixes of our IDs. After Nitit joined (whose ID starts with L), we renamed ourselves “Longest SubRoutine” (which in some sense also corresponds to this historically longest ICPC season).

The regional competition was scheduled for February 2022, which would be our first opportunity to test our abilities as a team.

Strategy/Division of Topics/Integration

During the December-January winter break, we trained continuously for more than ten sessions, gradually becoming familiar with each other’s styles despite some initial difficulties.

During this time, chenjb, who was pursuing a PhD at Georgia Tech and was previously Sub’s teammate, began coaching our team, occasionally analyzing our training results and our competitors.

Guidance from coach chenjb

We also participated in several training camps during our spare time and summer break, including Moscow Pre-finals, ByteDance Pre-finals, and Fake NAPC. After being repeatedly challenged by teams from different regions, we gradually developed our own team style and division of topics.

Initially, since both Sub and I were versatile competitors (except for geometry, which only Sub was proficient in), we didn’t have a clear division of different problem types. Generally, whoever had an idea for a problem would start writing the solution, while Nitit would participate in discussions and code solutions when he had ideas.

As we continued training, I realized I was relatively good at problems with substantial but clean code structures, but less proficient with problems involving complex case analysis or numerical calculations. After discussions with Sub, we decided that I would be responsible for flow/string/graph/data structure problems that typically required longer templates, while the versatile Sub would handle math/geometry/DP and simulations. Nitit would focus on math/DP while providing ideas to teammates, making observations, and verifying our approaches. Most of the coding was done by Sub and me. As the team captain handling the grunt work, I was responsible for organizing our templates.

In my early days of competing on Codeforces, I would often look at other solutions after solving a problem, finding shorter and cleaner implementations for each problem. This led to my requiring relatively less machine time in ICPC and being able to develop elegant, clean implementations for classic patterns. After sufficient planning off the machine, I could efficiently complete the code on the machine. Sub’s strength was his willingness to tackle any problem, making him effective for geometry/simulation/case analysis problems where he could debug complex approaches on the machine.

This system gradually took shape before the North American Finals in May 2022. As each person adapted to their role, we performed strongly in the North American Championship, which had many solvable problems, finishing behind only MIT and Swarthmore, who were in excellent form. This system became the foundation of our approach all the way to the World Finals.

Long-standing rivals

February 2021. We successfully won the regional competition with all problems solved, and we then achieved third place in the North American Championship in May, meeting our goals in both competitions. However, after completing all problems in 3 hours and 40 minutes at the regional competition, we discovered that Swarthmore College had finished all problems in just 2 hours and 15 minutes in the Mid-Atlantic Regional, which used the same problem set. In the North American Finals, although we achieved our goal of placing in the top three, we finished third, losing Swarthmore by one problem.

Since then, we have regarded Swarthmore as a long-standing rival, and we compare ourselves when they are also training. In the North American region, unlike MIT, which is way above our level, Swarthmore is more like a formidable opponent that we can chase, and we hoped to avenge them in the World Finals.

North American Finals results: With a small penalty time, we didn't complete problem B in time and narrowly lost to Swarthmore

Mindset/Personality/Rapidly Evolving World

Personality Changes

After the North American Finals in May 2022, I began my PhD at UChicago, where many events forced my personality to grow, making me more assertive and determined. I also started reading psychology books, gradually learning techniques to handle pressure in competitive situations. (I recommend The Inner Game of Tennis and The Power of Now). This helped me become a captain who could handle pressure and encourage teammates.

Repeatedly Delayed Finals

The previous season’s World Finals in Dhaka was scheduled for November 2022, so our finals would need to wait until after that. After the North American Finals, rumors circulated that the World Finals would be held in November 2023, with ICPC deciding to hold two consecutive WFs together to catch up on the schedule. This was later confirmed, with the dates set for November 12-17 at the Egyptian resort of Sharm El-Sheikh. After returning to the US in September 2023, I began preparing with my teammates for the final push. As this was my last chance and I wanted to perform well (plus the research pressure), I felt immense stress during the later stages of preparation, nearly burning out. However, after gradually adjusting (with some mental support from coach rpeng), my mindset returned to normal.

Mental support from Professor Peng

In early October 2023, the Israeli-Palestinian conflict intensified. Egypt is Israel’s neighbor, and Sharm El-Sheikh is even closer to Israel, increasing the possibility of the competition being postponed. On the second-to-last Friday evening before the competition, while Sub and I were running virtual participation on the 2011 World Finals, we received news that the competition was postponed, with new dates in March or April 2024. (Coincidentally, the 2011 World Finals was also originally scheduled for Sharm El-Sheikh, Egypt, but was forced to relocate to Orlando, USA, due to the Arab Spring.)

Competitors Withdrawing

After the postponement, the original pressure was lifted, and we rested until early 2024 before resuming weekly training. The competition was rescheduled for April 14-19 in Luxor, Egypt. When we resumed training, I consciously monitored my anxiety and avoided putting too much pressure on myself.

A month before the competition, we heard two pieces of bad news for North American teams: Swarthmore’s entire team had withdrawn, and Georgia Tech would compete with only two members because one team member’s US visa had expired and they had started working. While this increased our chances of winning a medal, it reduced the competitiveness of North American teams and eliminated our opportunity to face Swarthmore again, leaving us somewhat disappointed.

Swarthmore's withdrawal

After some reflection, I realized that perhaps the most important thing wasn’t defeating a specific opponent, but overcoming my own fears and performing at my best. So in my pre-competition social media post, I wrote a somewhat dramatic line: “The first and last opponent is always yourself.”

The Official Competition: Journey to Egypt

Pre-Competition Preparation

Visas

Sub and I, as Chinese citizens, could directly apply for Egyptian e-visas, which were approved in three to four days. However, Nitit, being Thai, faced a more complex visa process that would normally take more than three months to complete, making it impossible for him to obtain a visa in time for the competition.

We sought help from ICPC officials, who kept telling us they were working on it. Our anxiety grew as time passed. Fortunately, two weeks before the competition, we finally received a temporary landing visa permit from ICPC, completing the final piece of the puzzle for our journey to the Egyptian finals.

Competition Expectations

Back in September of the previous year, chenjb and I analyzed our opponents for the WF and found that the competition would be fierce, with more strong teams than in any WF since 2019. We estimated that about six teams would be very difficult to beat, with at least nine other teams at a similar level to ours. So our pre-competition expectation was to aim for a medal, which would require a good performance.

An analysis on the Codeforces rating of the other teams. The teams we can definitely not beat is labeled in yellow, while the teams that are on similar level are labled in green.

Arriving in Egypt

All three of us departed from Chicago. Since there are no direct flights from Chicago to Egypt, we first flew nine hours to Rome, waited five hours, then flew three hours to Cairo. After a five-hour layover in Cairo, we took a one-hour flight to Luxor. The complex itinerary made booking tickets a nightmare, and the actual journey with all the layovers and transfers left us exhausted. Since we didn’t have training that weekend, we simulated the recent Latin America Championship on the flight to Rome. With relatively simple problems and everyone in good form, we completed all problems in just over four hours, ranking 19th on the UCup leaderboard.

Before departure, I checked the weather forecast, which predicted maximum temperatures of 40°C (104°F) across Egypt. Despite some mental preparation, the actual heat was still overwhelming. Fortunately, my teammates had sunscreen, and HUAWEI provided everyone with an umbrella, giving us some tools to escape the heat. After arriving in Luxor, adjusting to the time difference was difficult, and the extreme heat drained much of my energy, often making me unbearably sleepy after 3 PM.

We had originally planned to use a recent CCPC Final as our last training session one afternoon before the warm-up contest, but after working for just over an hour, Sub and I fell asleep, forcing us to abandon the plan. However, in the two days before the competition, both Sub and I rested well, and Nitit had enough rest too, so we managed to store up sufficient energy for the official competition.

Team photo taken at registration

Dress Rehearsal

During the warm-up contest, we found a problem we had recently practiced (about calculating the expected profit from an optimal exit strategy in a casino). Since we had seen the solution, we knew there was a very simple approach (without using nested ternary search). After Nitit derived the formula, I implemented and optimized it, and after a few submissions, we got the first solve for that problem in the warm-up.

During the HUAWEI Challenge, I found it difficult to adapt back to Linux/Windows keyboards after being accustomed to Mac keyboards. So during the open practice, I decided to type several templates to verify our template hash while getting more familiar with the keyboard. By the end of the open practice, I finally felt comfortable with the keyboard. Sub was already familiar with the keyboard, so he didn’t need extra practice.

The on-site mouse would paste the clipboard content when the middle scroll wheel was pressed, which Sub and I frequently triggered by accident, which was annoying. While familiarizing ourselves with the keyboard, Peng Bo from Zhejiang University passed by and showed us a simple command to fix this issue. After making the change, we never accidentally triggered it again (thanks pb🙏).

After the warm-up ended, we felt tired, so we went back to rest and quietly awaited the official competition the next day.

Writing all the stuff we need to code at the beginning of the contest on our template

The Actual World Finals

Before the official competition began, I told my teammates that some teams better than us would certainly underperform, and some teams weaker than us would overperform, so we should focus on our own performance. The early scoreboard wasn’t important; we just needed to identify which problems were solvable. I encouraged the nervous Nitit, saying we would help each other if anyone got stuck on a problem. I asked Sub if he was nervous, and the seasoned competitor said he was fine, so I just briefly reminded him: “No need to rush, let’s take it steady.”

(Note: In this competition, problem IDs ranged from P to Z)

Early Stage

As I was coding the header, Sub said he had solved problem P and started coding. Six minutes in, we saw Oxford solve problem Y. After reading it, I came up with an intuitive and concise solution. Nitit agreed it was correct, so I spent a few minutes implementing it and got it accepted, giving us our first solve of the competition. Meanwhile, Sub continued working on P, and Nitit read problem W and suggested a solution that seemed correct (approach: ask about any three of the first four questions that are mutually linearly independent, then distinguish between 4 different cases in the last question). Nitit said he didn’t have a proof, but after thinking briefly, I provided an intuitive one. We had Sub step away from the computer, and I implemented the solution, which was accepted. Three minutes later, Sub also finished coding P and got it accepted. By the 32-minute mark, we had taken first place with our rapid pace and maintained it for 20 seconds, after which only the speed-focused CMU team ranked ahead of us. Before the competition, I had told my teammates that the early scoreboard, whether good or bad, didn’t mean anything, so we all remained focused and continued looking at the remaining problems.

Left: Reaching first place after solving the third problem. Right: Sub working on problem T

Middle Stage

Then we entered an incredibly challenging middle stage. Problems Q, T, and U had been solved by some teams. After reviewing the problems, Sub had an approach for the geometry problem T and began coding, mentioning it would take a while. Nitit and I started thinking about Q and U. After Nitit explained his solution for U to me, I understood the approach, but since it involved complex case analysis, we decided to leave it for Sub to implement after he finished the geometry problem.

A while later, Nitit gave me his approach for Q, and I began implementing it. Sub’s submission for T returned WA (Wrong Answer), so he started discussing the issue with Nitit. After I finished Q, I quickly debugged it, passed the sample cases, and submitted, but received WA. I stepped away from the computer to discuss with Nitit what might be wrong. The formula and implementation for Q were clean, but the input order was unusual. Nitit and I agreed that this was likely the issue, so I removed the permutation reverse indexing and resubmitted, which was accepted. Meanwhile, Sub had created a test case that revealed the error in his program, and after fixing it, he resubmitted and got AC.

At this point, we were around 15th place. Sub began implementing Nitit’s idea for problem U, while I looked at other problems. About 20 minutes later, we had our first version of U, but it received WA upon submission. Since we didn’t have another problem to work on simultaneously, and problem V had already been solved by 5-6 teams, I decided to implement a brute force solution for U while Sub looked at the more mathematical problem V.

Problem U involved outputing a construction for the optimal solution. After implementing a brute force approach, we discovered we had missed some cases. Sub fixed it, but the submission still received WA. I continued working on the computer, adding some special case testing, and discovered another case where our solution wasn’t optimal. After Sub fixed it, we finally got AC. Through our collective effort, we reached 6 problems and around 15th place, with the competition entering its fourth hour.

Left: Anxiously waiting for the result of our first submission for U (which returned WA). Right: I start implementing a brute force solution for U

Late Stage

While I was implementing the brute force solution for problem U, Sub had figured out an approach for problem V and verified it with Nitit. After we solved U, Sub began implementing V. Meanwhile, Nitit and I continued thinking about the remaining problems without much progress. Sub soon completed V, but the sample didn’t pass. After some investigation, we found that Nitit had slightly misunderstood the problem statement, but fortunately, the main approach didn’t change. After some modifications by Sub, the sample passed, and the submission was accepted! He had completed and solved the problem in just 37 minutes on the first try! With an hour and a half left in the competition, we had reached 10th place, finally overcoming the difficult middle stage.

At this point, three teams had solved problem R, and except for problem X, which only MIT had solved, no other problems had been solved. After discussing R, Sub guessed that if two cycles intersect, any permutation could be sorted. After discussion, I decided to implement a brute force program to confirm the pattern. The brute force revealed that in a biconnected component, if cycles intersect and there’s an even cycle, the answer is always sortable; without an even cycle, it depends on the parity of the number of inversions. Following our strategy of prioritizing Sub on the computer in the last hour, we decided to let him implement this problem. After Sub had been coding for a while, I checked the scoreboard and saw that 5-6 teams had solved R. This meant that to finish in the top twelve and win a medal, we would likely need to solve R, and if we could do it with minimal submissions, we might secure a medal. So we decided to focus all three of us on this problem to solve it together before the competition ended. I had Nitit create 5-6 additional test cases and draw out the graph structures to help Sub debug, while I took over the computer to help Sub with some of the coding pressure. Before the scoreboard froze, we had dropped to 12th place, confirming our initial guess that without solving this problem, we would miss out on a medal. But there was no time to panic; everyone focused on doing their part. I implemented the array minimal representation, inversion count, and Tarjan’s algorithm for biconnected components, testing the code on various data to ensure correctness.

Left: Sub concentrating on coding problem V, completing it in 37 minutes and getting it accepted on the first try (so strong!). Right: Approaching the scoreboard freeze, implementing templates needed for problem R

P.S. It’s worth mentioning that in a Universal Cup competition a few weeks earlier, there was a problem (I: Color Cycles) about information about edges within biconnected components. At that time, I got stuck for most of the contest because I wrote Tarjan’s algorithm incorrectly. Afterward, in frustration, I added a template with information about points and edges within biconnected components to our team’s templates. Unexpectedly, this came in handy during this competition (as we needed to determine if a graph was a cactus without even cycles), saving us a lot of time that would have been spent devising an implementation.

After completing and verifying the templates, we reached 4 hours and 10 minutes into the competition. Sub focused intensely on completing the remaining code, debugging through the test cases Nitit had created. With 20 minutes left in the competition, we made our first submission, which returned WA. At this point, I created a test case with a more complex tree structure, helping Sub identify an issue in the case analysis. After fixing it and passing the sample cases, we had 8 minutes left when Sub submitted again. We all held our breath, silently hoping. The pending time for this submission seemed exceptionally long, giving us a good feeling. After what felt like an eternity of ten seconds, the screen returned CORRECT!

With the final eight minutes, there were no more problems we could solve, so we let Nitit, who hadn’t touched the keyboard during the entire contest, implement an O(n^3) solution for problem S as the competition came to an end.

After the competition ended, we began calculating our possible ranking. Since some teams had many submissions for problem R after the scoreboard freeze, even if they solved it, their penalty time would put them behind us. After calculations, we estimated we would rank around 9th. Tsinghua University had a submission for problem R in the last minute, and there was news that they had solved one problem after the scoreboard freeze. We guessed they had solved problem X, which had only three submissions and was completed at the 274-minute mark, so with the same number of problems but lower penalty time, they would still rank ahead of us.

Submission status after the scoreboard freeze

Award Ceremony and Unfreezing the Scoreboard

Securing a Top 12 Position

Although our calculations indicated we would definitely get at least a bronze medal, it still felt surreal when we officially secured a top 12 position. Winning an ICPC medal had been a dream I’d been fixated on for three years. There were many times when I felt the gap between us and stronger teams, which was discouraging, but in the end, with some skill and plenty of luck, we actually achieved our dream.

Securing a top 12 position
An Unexpected Joy

When the final rankings revealed Tsinghua’s submission for problem R, we were surprised to find they had solved it. This meant that if Tsinghua had only solved R and not X, they would have the same number of problems as us but with more penalty time, allowing us to rise to 8th place and win a silver medal. Before Tsinghua’s result for problem X was announced, we all took a deep breath, awaiting our fate. The commentator announced the result was Wrong Answer, and we had successfully won a silver medal!

Going on stage to receive the award felt like a dream. Even when we solved R at the 292-minute mark, I never imagined we would be so lucky as to win a silver medal by a mere 36-minute penalty advantage over Tsinghua and Tokyo University. The three problems we solved quickly at the beginning seemed to have given us just enough of a penalty time advantage. If we had made one more mistake at any stage, our penalty time might not have been enough to secure a silver medal. We were truly blessed by fate.

Looking at the entire competition, despite many twists and turns in the middle, we were able to support each other and push through to the final decisive stage. Combined with Sub’s personal skill explosion and the final decisive moment, we were able to deliver this strong comeback performance. Standing on the podium at the World Finals felt unreal. After many ups and downs, we finally stood on the award stage of the World Finals, with hearts full of joy and emotion.

Left: Going on stage to receive the silver medal. Right: Final standings

Conclusion

The Gears of Fate

In 2018, to avoid wasting two WF eligibilities, I, a sophomore in the relatively weak North American region where qualifying for WF was easier, didn’t participate in that year’s regional competition. Instead, I served as a co-coach helping organize the school’s training, preserving two WF eligibilities for later years.

The 2019 ICPC World Finals was held in Porto, Portugal. Because the head coach Dieter couldn’t attend, I went as a co-coach with UW-Madison. In that WF, Peking University from the EC region finished 13th, missing the bronze medal by a 49-minute penalty difference from 12th place. ICPC didn’t award PKU an additional bronze medal, which resulted in the EC region losing a direct advancement slot to the World Finals the following year.

In the new season that year, Zhejiang University’s Legilimens team placed fourth in both the Xuzhou Regional and EC-Final, but partly due to the EC region losing the direct advancement slot, they missed the opportunity to advance to the WF that year.

In 2021, Nitit, who was in his first year as an undergraduate at UWM participating in the regional competition, lost to another team from the same school due to penalty time disadvantage, missing the opportunity to advance to the next stage and compete for a WF slot. He decided to participate in the regional competition again the following year.

That same year, Subconscious, a Legilimens team member with one WF participation remaining, came to North America, and I, having finished my gap year, returned to campus with my last WF opportunity. Sub and I became teammates for each other’s last WF, and with Nitit, we formed a team with complementary abilities. Meanwhile, chenjb (also a Legilimens member), who came to North America with one remaining WF slot, became our team’s resident coach.

The rest of the story is as described above. If seven or eight things hadn’t fortunately happened in this exact order, we probably wouldn’t have had a team capable of competing at the world level, and the exciting story above wouldn’t have existed.

Pure Joy

However, looking at it from another perspective, if we hadn’t solved problem R and missed out on a medal, would all these years of effort have been worthless? Would our story be any less exciting?

I remember in August 2017, having had little exposure to online competitions, I joined my first CF contest after hearing others mention Codeforces. My feelings then were pure - I enjoyed the thinking process, and being competitive by nature, I also enjoyed competing alongside thousands of others. Later, at school, we developed an active competitive programming community where we cultivated this hobby together and learned from each other, giving me a strong sense of belonging.

But in the final stages, when I became too focused on my goals, I seemed to forget the joy of the process. The greatest meaning of these seven years isn’t the medal we ultimately won, but the enjoyment of solving problems in pursuit of our goals and the happiness of seeing our skills gradually improve. Years later, we won’t forget the joy of defeating opponents or the frustration of being defeated, nor will we forget the excitement of solving various problems with elegant solutions, or the relaxation of walking together on University Ave bathed in sunset after training, listening to the wind.

In the Pixar movie “Soul,” there’s a story about a little fish wanting to find the ocean, not realizing it had been in the ocean all along.

Whether the outcome is good often depends on luck, but the bittersweet experiences of the journey are always there, and their meaning far exceeds the significance of the result. Perhaps I’ve been in the “ocean” all along?

Final Thoughts

With this competition’s end, my seven-year competitive programming career also comes to a close. In the coming seasons, I’ll likely continue this journey in a different role as an ICPC coach at the University of Chicago, while also looking toward broader horizons and seeking new passions. I’ve grown tremendously over these seven years, made many like-minded friends, and learned to coexist with myself while competing with the world. These are the precious gifts that competitive programming has given me, and I hope to carry them forward.

See you in the next journey!

Best wishes to all.

P.S. I’ve attached a photo of a hot air balloon in Luxor, one of the few highlights of this Egypt trip. While riding the hot air balloon, I met Mike Mirzayanov, the founder of Codeforces. I encounter Mike at every World Finals, and this time I was fortunate to take a photo with him and also use my camera to take pictures of him and his family on the hot air balloon.

P.P.S. Easter egg: Thank you (dear reader) for making it this far! Here’s a video of our team’s celebration at the moment we so luckily solved problem R at 292 minutes: Video link.

Left: Beautiful hot air balloons in Luxor. Right: Photo with Sub and Mike

Acknowledgments

  • My amazing teammates Sub and Nitit
  • Coaches Dieter, chenjb, and Professor Peng for their selfless help (dream coaching team)
  • Friends in the competitive programming community:
    • YaoBIG
    • ICPC teammates at Madison: lsh, senior zjm, ysc, csr, bvd, Jirayu
    • Zhuolin Yang and Yen-Hsiang Chang
    • Runze
    • tls(tangjz), qls(quality), and senior fsy, wzj and wxx whom I met in Beijing
    • Guo Shen, who trained with me during the summer of my sophomore year
    • Teacher Jin Jing from my high school informatics competition
  • QOJ and Qingyu for providing the training platform (I forgot to take a photo with Qingyu!)
  • Friends in life who have always supported and encouraged my growth
  • And my competitors, who helped me become stronger through our competition

Thank you all!