IOI 2025, Sucre, Bolivia - 3 Bronze 1 Gold!
- Day 0–1: Arrival
- Day 2: Practice + Opening Ceremony
- Day 3: Excursion (City Tour)
- Day 4: Contest Day 1
- Day 5: Excursion (Castle) and Padel
- Day 6: Contest Day 2 + Talent Night
- Day 7: Closing Ceremony
- Day 8: Departure
Day 0–1: Arrival
Yan Xun:
This year’s journey was especially long, as we had to take five flights spanning about 40 hours to reach Sucre. The first two legs went smoothly. Upon arriving in Santa Cruz, Bolivia after the third leg, we were all worried as we had less than half an hour to make our next flight. To make matters worse, we were informed we had to complete our visa in Santa Cruz instead of upon arrival in Sucre. Thankfully, there were multiple IOI staff (who were unfortunately not very fluent in English) at the airport to help us out. We boarded the plane 7 minutes before the scheduled departure time and arrived in Sucre at 9pm local time. We were greeted with applause from some IOI staff and we were handed Bolivian flags. After a long, arduous journey, we arrived at our accommodation, Villa Bolivariana at 10:30pm local time. Two delegations shared a room, and we were assigned to share a room with the Colombian team.
Day 2: Practice + Opening Ceremony
Yan Xun:
We started the day with the practice contest. We had to wait outside the contest hall for over an hour before entering, and the practice contest had to be delayed by 15 minutes. The provided keyboards were in Spanish layout, which was quite different from what we are used to. Yan Xun and Chang Jun had brought their own keyboards, Isaac was fine with using the Spanish keyboard (orz Isaac), whereas Shao Qian and Jun Xing tried to help Yuichiro remap the keyboard layout. Jun Xing also taught us to use the provided compile.sh and submit.sh files. Many team leaders were going out to buy US layout keyboards for their contestants, so we managed to get two keyboards, one each for Isaac and Yuichiro.
We had lunch and took the bus to the opening ceremony venue, the Biblioteca. We were greeted outside the venue by some performers in traditional Bolivian clothing playing some local instruments and dancing. We had to wait about half an hour for everyone to arrive before the opening ceremony began. Then there were more speeches, more dancing and a violin performance. (I (Yan Xun) was constantly dozing off due to jet lag) After that, each delegation was called in alphabetical order and displayed on the screen. Most countries waved to the camera, while some threw items towards the crowd. This entire process had to be repeated because apparently some countries weren’t called the first time. We commuted back to the hostel to rest. That night, we were informed that my keyboard was rejected, which caused me to worry for a while. Luckily, we managed to buy a keyboard from the Polish team so our entire delegation could use US layout keyboards.
Day 3: Excursion (City Tour)
Yan Xun:
We left the hostel at 8:30am for a half-day city tour of Sucre. We had a tour guide bring us around, explaining the historical significance behind the locations. When our bus arrived at the city centre, we were greeted by some enthusiastic zebra mascots (who were there for the 200th anniversary of Bolivia). First, we were brought to the rooftop of a governmental building overlooking the city. We were given a few minutes to enjoy the view and take pictures.
While walking to our next location, we spotted a roadside newspaper seller, with IOI making the headlines of that day’s newspaper. We bought a few copies as souvenirs (day 1 p1 reference!!).
We then visited Casa de la Libertad, with portraits and statues of the founding fathers, as well as all the presidents in Bolivia’s history. After that, we visited Plaza 25 de Mayo, which was a square in the city center, Casco Viejo. There was a statue of Simon Bolivar in the middle of the square, who led Bolivia to its independence. The team leaders tried juice from a nearby street side fruit juice vendor.
The bus then picked us up to bring us to Simon Bolivar park, the biggest park in Sucre (which was unfortunately quite small), where all of us got ice cream. Finally, we ended the excursion at La Ricoleta, the oldest part of Sucre with lots of Spanish colonial buildings. We entered an indigenous museum, which had a focus on ancient textiles made of alpaca and llama wool.
We had free time all the way until the end of the day, so we were worried we would have nothing to do for such a long time. After resting in the room for a short while, Chang Jun and I decided to walk around and see if there was anything going on. We saw some sponsors waiting to set up lego sets around on the ground floor. While waiting, we talked to an ex-IOI gold medalist from China, who was at this year’s IOI as a sponsor representing OpenAI. We spent the next few hours building a (rip-off) lego motorbike with contestants from other countries, before going back to our room to rest early for the first contest day.
Day 4: Contest Day 1
Tasks: souvenirs, triples, worldmap
Isaac
After reading through the problems, I tackled problem 2, Triples, first. I figured out that there were 6 cases, one for each permutation of distances. I implemented 5 of these cases in , with the remaining case needing quadratic time. After some debugging, this earned me 34 points, including the subtask where , even though that shouldn’t have been able to pass in quadratic time. Removing the quadratic case, I gained 11 more points from subtask 4. I would get subtask 2, worth only 6 points, later.
I moved on to problem 3, World Map. Using a tour of the vertices, I divided the grid into vertical strips of length 3, getting a basic solution, giving 58 points for what I felt was for free.
I finally decided to get some points on problem 1, Souvenirs. When I first read the problem, I thought that you would get as many copies of a souvenir as possible, which would be impossible to solve. Re-reading the problem, I found that each transaction could actually only give at most one souvenir of each type. I skipped the subtasks, as they felt too easy. I made the observation that querying the average price of a group of souvenirs would never yield the highest priced souvenir, but would get one relatively low-indexed souvenir. This would get me an AC. I implemented my solution, modifying the grader to log the transactions, and submitted my solution, which immediately passed.
After solving problem 1, I had over 200 points. I wondered if I could surpass 250 points on the first day alone. I spent some time on the output only section on Problem 2, earning 8.8 points using beam search and simulated annealing.
I returned to problem 3, optimising my solution slightly, to , though I expected it to have instead, so I didn’t submit it. I then explored the idea of using nested L shapes, where only one of the sides needed to be of width 3, increasing each dimension by 2 on average. Submitting my solution, I did not expect to get 86 points, my solution attaining , instead of the 72 I had intended to get.
In the remaining time, I was unable to get any more points on Problem 2, but I implemented the 6 point subtask on problem 2, submitting my solution only 12 minutes before the contest ended.
My score for Day 1 was 100 - 59.8 - 86, a total of 245.8 points, putting me at 18th place overall, and 13 points above the gold medal cutoff for the day. I suspected that my performance for Day 1 was because all the problems were ad hoc, just like the APIO this year.
Yan Xun
I had changed my strategy slightly compared to last year, and decided to spend 40 to 50 minutes per problem in sequential order so I wouldn’t miss any extremely easy ideas due to overcommitting on one problem. Working down the problems in the order they were listed, I wrote down as many observations as I could make and grabbed the easy subtasks. On problem 1 (souvenirs), I managed to grab 39 points with some simple casework. I had a few ideas that could potentially lead to a full solution, but at that time 50 minutes had passed so I proceeded to problem 2.
There was an obvious brute force solution to p2 by simply iterating over every triplet. Not long after, I figured that if we fixed the leftmost and rightmost element of the triplet, there can only be amount of candidates for the middle element, giving an solution. I implemented this within 10 minutes, giving me 18 points. I also knew how to do subtask 2, but I put off the implementation as it was only worth 6 points. I then turned to the output only section of the problem, which was worth 30 points. I failed to find a construction after a while, so I wrote a simulated annealing solution giving me 7.86 points. At that point, 1 hour and 40 minutes had passed, so I moved on to p3.
First of all, I noticed that the problem never mentioned that the graph was connected, yet there was an subtask. I spent 5 minutes proving that the graph must be connected, then worked down the special case subtasks (the graph is a path, the graph is a tree, the graph is complete). I quickly figured out an Euler tour solution for the tree case, but I did not implement it yet as solving the general case (even with an inefficient solution) instantly yields 58 points, including all the special case subtasks. I figured that I could extend my solution for the tree case into the graph case in about 5 minutes. First, I implemented the tree case solution to verify my idea, giving me 15 points. I took another 13 minutes to implement my general solution, which was worth 72 points. At this point, half the contest time had elapsed, and unbeknownst to me at the time, I was above the gold cutoff.
For the second half of the contest, my strategy was to work on the subtasks/full solutions that seemed the most doable. Since I had a few unfinished ideas from p1 earlier, I decided to revisit them and see if they got anywhere. I implemented a solution to the second last subtask that seemed correct and realised it got WA on my hand written test case. I realised the solution was completely wrong, and after a few more failed ideas, I gave up and turned to p2. I quickly finished off the 6 point subtask from p2 in 2 minutes by modifying my solution. Subtask 4 hinted at doing some casework based on the relative ordering of the elements of the triplets, so I began systematically figuring out each of the cases. There were 6 cases in total, and I had already figured out the solution to 4 of them while solving the early subtasks. After about 10 minutes of thinking, I managed to come up with a solution to the 5th case, giving me the illusion that I was really close to a full solution. The 6th case seemed perfectly symmetrical to the 5th case, so I spent 30 minutes trying to find the symmetry. I then wrote out a few equations representing the cases, and I realised the 6th case was special because there was no overlap in variables. I spent another 30 minutes drowning in algebra, desperately trying to find an invariant that would result in an solution (turns out I was constantly trying to run through a brick wall, since the number of solutions to the last case was bounded by . I quickly ran a few more runs of simulated annealing, modifying various parameters, increasing my score by about 2 more points.
Since only 50 minutes of contest time remained, I decided to go back to p3 and p1 to ensure that I didn’t miss any easy ideas. I spent 10 minutes on each problem, making no significant progress. I did think of rotating the square 45 degrees for p3 (which was the solution to 86 points!), but due to time pressure and p2 constantly on the back of my mind, I did not figure out the details, and concluded that rotating the square would not result in a better solution.
I ran my simulated annealing code for p2 a few more times, but no better solutions were generated. I spent 15 more minutes thinking of the full solution to p2, and finally, in the last 7 minutes of the contest, I decided to implement a solution that would probably TLE but maybe pass the subtask as a last resort. I made two submissions, but both had bugs due to double counting. I ended the day with a score of , feeling quite disappointed as I couldn’t make any significant progress for the second half of the contest. I finished day 1 in 115th place, in mid-high bronze.
During the analysis session, I talked to a member of the Thai team, and found we had really similar scores and experiences (both of us gained no points in the second half). I got comical reactions from him and Jerome from the Filipino team when I explained the 86 point solution to p3, which seemed extremely obvious once mentioned. I also learnt from them that a lot of solutions passed the subtask for p2, which made me regret not coding my last resort solution sooner.
Yuichiro
Before the contest started, I was very nervous since it was my first time at an International Olympiad. Once the contest started, I read through all the problems statements and started with problem 2 where I solved 2 of the easy subtasks worth 18 points with an solution and tried the output only section but I didn’t find any construction so I just used beam search, which got me 8.21 points.
I moved on to problem 1 where I did the easy subtasks which got me 39 points. I made the observation that the average price of a group of souvenirs is less than the most expensive souvenir in the group but I didn’t think it’d work since it would skip souvenirs which are more expensive than the average price but less expensive than the most expensive souvenir.
I then moved on to problem 3, where I did subtasks 1, 3 and 4 which got me 20 points. I returned to problem 2 and ran my beam search code again but it only got me 1.15 more points so I returned to problem 3 and solved subtask 2 worth 10 points by making a world map that looks like the tree and I only realised later in the contest that this was equivalent to an Euler tour which I could have implemented much faster.
I returned again to problem 2 to solve subtask 2 worth 6 points and ran my beam search code again which got me 0.16 more points.
I returned to problem 3, where I thought of an R=4 solution worth 72 points which involved modifying my solution to subtask 2 but because of my bad implementation for subtask 2, it took me a long time to debug and by the time I had finished debugging, I only had half an hour left.
I then solved subtask 4 for problem 2 worth 11 points, which was also an easy subtask. After this, I only had 7 minutes left so I just ran my beam search code again but didn’t get any more points.
I ended the day with points, putting me in 118th place and 15 points above the bronze cutoff which I was quite happy with. I think I should have spent less time on the output only section of problem 2 since it was only worth 30 points and I got 9.52 points from it.
Day 5: Excursion (Castle) and Padel
Jun Xing:
We were brought to visit a castle. Personally, the castle was not fascinating. Our tour guide showed us around for about an hour until 10am, then announced that it is free time until 1:30pm. Shao Qian and I sat down in the garden for tea break and chatted with other leaders (e.g. Indonesia) and sponsors (HRT).
Later we saw that contestants were broken into teams for a sporty competition. One of the events were people lining up and having someone crawling under their legs. The competition ended with capture the flag. While the contestants were in the event, Shao Qian and I found a dog in the garden. We didn’t know whose dog it was, but it loved to fetch sticks that we threw, sometimes holding it tightly in its mouth like its credit card information. I had lots of fun playing fetch with the dog.
We had free time in the evening. Mateo (our tour guide) brought our contestants to play Padel, a sport that looks like a squash-tennis-pickleball hybrid. It turned out that Mateo organised a match with Belgium, and they were a lot better than us. We still had fun however. It was good to do light exercises (because we couldn’t make the games last very long…) before the contest tomorrow.
Day 6: Contest Day 2 + Talent Night
Tasks: festival, migrations, obstacles
Isaac
To start, I focused on problem 1 of the contest day, Festival. I started implementing a 27 point DP solution, sorting each type of coupon in increasing order of price. However, when I submitted my program, it was already 50 minutes into the contest. I read problems 2 and 3, problem 3 seeming to be easy enough to get all but the final subtask. I used DSU and segment tree, eventually getting my 83 points halfway through the contest.
I went back to problem 1, observing that for subtask 6, you can buy very few coupons not of type 1 without running out of tokens. I modified my subtask 4 solution to work with subtask 6, and got 16 more points.
This late into the contest, I had to make sure I kept up my score, so I moved to problem 2, unable to think of any solution for the main subtask, so I did subtask 1, gaining 30 more points.
For the rest of the contest, I tried to claim the remaining subtasks of problem 1. Using a few equations, I observed that there was an order for which coupons to buy. I only realised much later that this order was the fixed point of the number of tokens for each coupon, such that buying it would not change the number of tokens you had. Hoping I would AC, I instead just solved subtask 6, 12 minutes before the end of the contest. Remembering that my DP solution could stop after any number of coupons not of type 1, type 1s always being the last, I copy and pasted the section of code in, submitting it with only 3 minutes left. I refreshed the page, the timer ticking down, until I saw my score increase by 12, my submission passing subtask 3.
My score for day 2 was 82 - 30 - 83, or 195 points. My overall score was 440.8 points, placing me at rank 27, within the gold medal range by only 4 points and 2 places. I feared that I would lose my medal, just like in 2022, but Shao Qian assured me that I was safe. It turned out that I was very close to losing my gold medal, my last submission 3 minutes before the end of the contest boosting me from 29th to 27th place.
During the closing ceremony, I would learn that Heng Liao, the gold medallist exactly on the cutoff, also barely made it to gold, gaining 12 points slightly earlier than me, This in turn pushed me into 29th place, leading to my gold medal clutch.
Yan Xun
Knowing that I was 25 points below the silver cutoff for day 1, I decided to take a risk for day 2’s strategy by spending most of my time on the communication problem which I expect to perform better on than the batch problems, maximising my chance to end up with a silver. Even if this strategy failed, I would still be able to secure a bronze by grabbing subtasks.
Since the first problem was a batch problem, I decided to spend 50 minutes on it as per my usual strategy. I grabbed the 24 point greedy subtask within 30 minutes, then started thinking of some simple greedy strategies that could potentially work for an AC/partial solution. I spent 20 minutes implementing and submitting them, but all of them got WA.
The second problem was a really fun communication problem, and it was clearly a problem that I could do well on. I first spent 30 minutes thinking of and implementing the solution for subtask 1, giving me 30 points. Soon after, I found that extending the solution to subtask 1 works for subtask 2 as well, and spent 30 minutes planning out a three-phase solution using ternary and binary encoding, worth 77 points. However, there was an overwhelming amount of implementation and casework going into this solution, and having to pay attention to so many details caused me to get WA 11 times over the next hour. In the process, I had to generate many different test cases that broke my code, as it was impossible to test the complicated casework covered in my code with a single test case. Since there were less than 2 hours remaining in the contest, I decided to put the problem off and grab some subtasks on problem 3.
I quickly identified 3 doable subtasks for problem 3, gaining 23 points by constructing the graph and doing a bfs, then another 14 points using a prefix sum. This took a total of 20 minutes. I spent 10 more minutes on the problem making no useful observations, so I went back to debugging my code for problem 2.
After 10 more minutes of debugging, I found a test case which I mistakenly thought that my solution couldn’t solve at all (turns out I just didn’t handle the casework properly and I fixed the bug within 10 minutes of the analysis session). I found a quick fix by converting to full binary encoding, a solution worth 72 points which I implemented in 20 minutes by modifying my initial code. I was surprised that a much simpler solution like this one with significantly less casework was worth so many points, and realised I shouldn’t have time sinked on a much more complex solution.
For the last 20 minutes of the contest, I tried to hopefully grab a subtask or two on p1. I quickly realised that an exchange argument could be probably used, but I somehow didn’t think of simply writing a comparator (solving the N=2 case) and sorting for an easy 27 points for the subtask where the answer is a permutation. Reading the condition for subtask 6, I also quickly realised by working on some cases by hand that there can only be at most decreases in before it reaches 0. Despite making all the observations required for the full solution, I didn’t have enough time to implement anything, and I also did not realise DP could be used to grab subtask 4 as well as the AC solution.
I ended day 2 with a score of , totalling to 133.89 points. I knew I would place quite low for this contest day as problem 1 wasn’t too hard, and there are relatively simple solutions for above 60 points on problem 2. I should have analysed the scoring function for problem 2 more carefully before implementing my best solution, as that would’ve saved me a lot of time. Thankfully, I was able to secure a bronze medal overall.
Yuichiro
Before the start of the contest, I was again nervous because I wanted to get at least a bronze medal. I started with problem 3, where I implemented a simple solution using DSU to solve subtasks 1 and 3 which got me 23 points.
I then moved on to problem 2, but I didn’t realise that subtask 1 had partial scoring so I submitted a solution which I thought would get 30 points but only got me 10 points.
I moved on to problem 1, where I did the first 3 subtasks which got me 24 points and should have been easy but I took a long time to debug because I forgot about overflow errors.
I moved back to problem 3 to solve subtask 2 using DSU which got me 14 more points.
I then returned to problem 2, where I noticed that I could just not send any messages until near the very end and then just send the answer in binary which got me the 30 points which I had expected earlier. I realised that this would also work for subtask 2, just by sending the 2 nodes in binary one after the other, and after implementing, it got me 72.89 points. I then noticed that when sending the first node I could use quaternary instead of binary which got me 6.22 more points.
I returned to problem 1, where I implemented an solution for subtask 4 using DP which got me 15 more points. I then tried some greedy solutions for subtask 5 but they didn’t work.
I then spent a lot of time thinking of a solution to subtask 5 or 6 for problem 1 but I couldn’t think of any so I moved back to problem 2 and added some randomness to my solution, since sending 0 doesn’t count as a message, which got me 1.06 more points. I spent the rest of my time thinking of a solution to subtask 5 or 6 for problem 1 but I couldn’t think of any and while I was thinking, I was also repeatedly submitting my RNG solution for problem 2 which got me 2.28 more points.
I ended the contest with points over both days which put me in 106th place, in high bronze, 24.04 points below the silver cutoff. Later when I heard the solution for problem 1 subtask 5 worth 27 points, I thought it was very obvious and was frustrated that I didn’t find it during the contest since it would have put me just above the silver cutoff. Overall, I was happy since I didn’t expect to be anywhere near silver.
Day 7: Closing Ceremony
Jun Xing:
Before the closing ceremony, we had our final GA meeting. Halfway through the meeting, we were given a pleasant surprise: an alpaca handler walked his alpaca around the room. The alpaca got stopped at the back of the meeting room by a crowd of team leaders, and we got to feed and pet the alpaca! (while the treasurer’s report was ongoing…) The alpaca’s wool was very soft.
This was Malaysia’s best result ever: We had our second all-medal year and our second gold! Congratulations to Chang Jun, Yan Xun and Yuichiro for winning bronze, and Isaac Hew for winning gold.
The closing ceremony went overtime and we were looking forward to the dinner, hoping it will be better than usual. Somehow, only after an hour, we were served our first appetizer, and 20 minutes later another appetizer. There was a whole ballroom of people bored and starved.
We decided to skip the dinner and go to the night market we learned about on Day 3. Coincidentally, gold medallists were called to get a prize from a sponsor. Congratulations to Isaac for getting money as a scholarship award from CodeMao! After that, we needed to get enough people to fill in a bus to go back.
The night market was fun. Mateo came to be our translator and currency exchange. We bought many alpaca plushies, had night market food (we were given free extra chicken!), and played foosball. We then went to the city center, watched a band perform for Bolivia’s 200th independence day.
Day 8: Departure
Jun Xing:
We left early in the morning as our flight was at 10am. Our first leg was once again delayed. Fortunately, we had no issues as our next flight was by the same airline (but some delegations missed their flight due to this). This time, we had time to explore the Doha and Sao Paulo airports. Food was very expensive. We safely arrived in Malaysia after another 40 hours of flight.