

Assorted Problems 3
Mostly old Luogu blue-difficulty problems I solved years ago, with quick sketches and short editorials.
Mostly old Luogu blue-difficulty problems I solved years ago — quick sketches plus short editorials.
P4317 The Flower God’s Number Theory Problem#
The answer is clearly , where is the number of times ones appear.
There’s a fairly obvious digit-DP approach, but it turns out I computed it with binomials.
Go from the high bits down. Suppose the current bit of is 1: place a everywhere you can before this position, leave this bit as 0, and then the remaining bits are free. Binomials handle the rest.
https://www.luogu.com.cn/paste/8ftcv19a ↗
P4430 Monkey Fight#
My favorite kind of find-the-pattern problem (not really).
Somewhere in the back of my memory is something called a Prüfer sequence, from which the number of labeled unrooted trees is .
Each such tree has edges, so the number of generated orders is .
Multiply the two.
https://www.luogu.com.cn/paste/5rfn8cdq ↗
P4514 God’s Seven Minutes of Problem Setting#
Tree-of-trees at a glance.
Looking at my code, it’s a 2D BIT.
Difference arrays on top of difference arrays give range add and range sum.
https://www.luogu.com.cn/article/u4lh1j1n ↗
P4550 Collecting Stamps#
Brain a little foggy.
Couldn’t derive an expected-value DP this simple. Rough.
https://www.luogu.com.cn/article/u3ul4p52 ↗
CF1000F One Occurrence#
Mo’s algorithm + set at first glance. Looking at my code, you don’t need a set — a stack works: record each element’s position in the stack, and to delete, swap with the top and pop.
Since it’s offline anyway, you can also sweep: sort the intervals by right endpoint.
Then for each value keep only its rightmost occurrence, and at that position record the previous occurrence, say . A range query then asks whether the minimum is ; if so that value appears exactly once. Maintain minima and positions with a segment tree.
https://www.luogu.com.cn/article/5nv0adca ↗
P4822 [BJWC2012] Freeze#
Layered graph + shortest path at a glance, though the constraints felt odd.
Looking at my code, there’s no problem. My mistake.
Build layers, and when connecting a layer to the one below, halve the weight.
https://www.luogu.com.cn/paste/4hwtsh6g ↗
CF1006F Xor-Paths#
One look at the submission timestamp told me I probably didn’t write this code.
Thought about it for a while with no ideas.
One glance at the “search” tag and it clicked.
Split along the diagonal and do meet-in-the-middle.
https://www.luogu.com.cn/article/6kwz3c7z ↗
P4910 Patchouli’s Bracelet#
DP plus matrix optimization at a glance.
But I’d blown up the DP state so it couldn’t be optimized at all. Unbelievable.
You don’t need the first element in the state at all — just adjust the initial values and case-split.
https://www.cnblogs.com/liangbowen/p/16945276.html ↗
P5021 [NOIP 2018] Building Tracks#
Ancient memories.
First, it’s easy to see you binary search the answer for the minimize-the-maximum part.
Above that, do a tree DP.
Each node can pass at most one track upward, so pair up its children’s tracks (binary search or a multiset both work) and pass the longest leftover upward.
https://www.luogu.com.cn/paste/bnbfvrsg ↗
CF1076E Vasya and a Tree#
I remembered it as a tree difference array but couldn’t recall how.
Looking at the code: you can hang all the modifications on the tree offline first, then apply the difference during the dfs, using a BIT to record difference values per depth and prefix-sum them. The dfs itself guarantees the difference values come only from the current node’s ancestors, and you remove the value on backtrack.
https://www.luogu.com.cn/paste/y1v2id1i ↗
P5122 [USACO18DEC] Fine Dining G#
First instinct was to build the graph and run a shortest path from n — and then I was stuck.
One skim of the editorial showed it isn’t hard; my thinking had gotten rigid.
Let be the shortest path distances. If node has a haystack , add a virtual node connected to with weight , then run another shortest path from to get a second distance array and compare.
https://www.luogu.com.cn/paste/jawppchr ↗
P5123 [USACO18DEC] Cowpatibility G#
Brute-force inclusion-exclusion at first glance, and I came up with a bogus version of it. Unbelievable.
Each cow gives inclusion-exclusion terms — but how do you count each result?
Looking at my own code, it’s delightfully brute force: sort the chosen numbers ascending, insert a separator between them to form a string, and store it all in a map. Not bad.
https://www.luogu.com.cn/paste/rlmxpht1 ↗
P5268 [SNOI2017] A Simple Query#
Blanked for a moment, then remembered it resembles a THUWC problem.
Consider a single value first, with a prefix sum counting occurrences of in the first elements.
The contribution of is .
Expand with the distributive law and it becomes a product of two prefix sums, which Mo’s algorithm handles easily.
https://www.luogu.com.cn/paste/95s712lj ↗
P5304 [GXOI/GZOI2019] Traveler#
Brain-lapse, didn’t get it. The extra-log approach feels more interesting than the intended solution.
https://www.luogu.com.cn/article/oow8gs0r ↗
P5505 [JSOI2011] Distributing Specialties#
I had the rough idea — inclusion-exclusion — but forgot about stars and bars. A bit embarrassing.
https://www.luogu.com.cn/article/ifavg4dm ↗
CF1197D Yet Another Subarray Problem#
I came up with a silly approach that might also pass?
Looking at my old code, it’s just a DP: group by residue, DP backwards, and maintain the suffix. Let be the DP value for right endpoints with .
At each , either set or keep the previous one, then update with .
Take the max of the two.
Then with as the left endpoint, consider the contribution of the right endpoint for each residue.
https://www.luogu.com.cn/paste/vr2e3ait ↗
P5589 Peppa Pig Plays a Game#
I got the DP recurrence and the pattern, but one detail wrong. Not too bad.
The general idea matches this:
https://www.luogu.com.cn/article/c187nysw ↗
CF1238F The Maximum Subtree#
I mostly worked out the properties, came up with a weird DP, then looked at my code and the editorial.
Turns out I’d just used a greedy. Interesting — silly me.
https://www.luogu.com.cn/paste/ed6j9k3r ↗
CF1238E Keyboard Purchase#
I saw it needed bitmask DP but couldn’t see how to account for the contribution. A bit of a blowup.
Looking at my old code, it’s rather neat: for each state, on each transition add the pairwise contribution between the set and its complement. Then when a letter enters the set, the number of times it has been counted beforehand is exactly the keyboard distance.
Easier to follow from the code.
https://www.luogu.com.cn/paste/imhc56ui ↗
CF1303E Erase Subsequences#
DP at a glance, and you can get there with a bit of thought.
Enumerate the length of , then let be the maximum number of characters of matchable when is matched up to position .
The DP isn’t hard; the code makes it clear.
https://www.luogu.com.cn/paste/hq2qo9u2 ↗
P6186 [NOI Online #1] Bubble Sort#
https://www.luogu.com.cn/article/duay9pls ↗
P6275 [USACO20OPEN] Sprinklers 2: Return of the Alfalfa P#
Analyzed it wrong. Doomed.
Drawing it out, the boundary between the two parts is always a staircase from the top-left to the bottom-right, so DP over that staircase: let be the state at cell with the staircase heading right or down.
Simple DP plus counting.
https://www.luogu.com.cn/paste/umu66048 ↗
CF1365F Swaps Again#
Zero ideas. Doomed.
You just need to guess the right lemma — and guessing lemmas used to be my strongest skill.
https://www.luogu.com.cn/article/w8jhbqpz ↗
P1857 Prime Stone Game#
A true classic, but years without training have slowed my brain.
It’s Grundy values first, computable with a linear sieve, building the SG array as the statement requires.
Then DP: for winning states finish as early as possible, for losing states delay as long as possible.
The transitions follow from the SG array.
Easier to follow from the code.
https://www.luogu.com.cn/paste/q8l5n8ih ↗
P2606 [ZJOI2010] Counting Permutations#
I saw it was a min-heap immediately and hand-waved a DP that looked about right.
Let be the number of min-heaps on nodes. Take 1 as the root each time, split into two subproblems, multiply the counts and a binomial:
There’s a detail issue — build a heap in advance to compute the left subtree’s size.
https://www.luogu.com.cn/paste/5bptgon9 ↗
P2743 [USACO5.1] Musical Themes#
I came up with a horribly convoluted approach and completely missed that you just take differences and DP.
: the first part ends at , the second at . Routine transitions.
https://www.luogu.com.cn/paste/sd8mu4o0 ↗
P3620 [APIO/CTSC2007] Data Backup#
Brain-lapse: after taking differences it’s just the tree-planting problem — the classic regretful greedy.
https://www.luogu.com.cn/paste/kcqz94b7 ↗
P3545 [POI 2012] HUR-Warehouse Store#
Max flow at a glance, then I realized it needs min-cost flow.
And then that it’s really just simulated min-cost flow (regretful greedy).
A priority_queue does the job.
https://www.luogu.com.cn/paste/uh0ia6ux ↗
CF900D Unusual Sequences#
My analytical ability is gone.
Let be the number of sequences summing to , ignoring the constraint.
It isn’t hard to see , by stars and bars: each gap is either split or not.
Let be the number of sequences summing to with .
Then
By inclusion-exclusion,
Just recurse.
https://www.luogu.com.cn/paste/e7ko1cep ↗
CF895C Square Subsets#
My thinking went sideways into DP, which does work, but a linear basis is the fastest approach.
First, is small and there are only 19 primes , which suggests a linear basis.
Let be the size of the basis after inserting everything.
Then the remaining numbers are linearly representable.
So the answer is .
https://www.luogu.com.cn/paste/rv65zn8y ↗
CF741C Arpa’s overnight party and Mehrdad’s silent entering#
I thought it was 2-SAT. Naive of me.
Build a bipartite graph and color it.
Couples obviously get an edge.
The “two of any three must differ” constraint gives edges .
The result is always bipartite: any cycle alternates a couple edge with an adjacency edge, so every cycle is even and no odd cycle exists.
https://www.luogu.com.cn/paste/81eqdo46 ↗
CF730I Olympiad in Programming and Sports#
Min-cost flow construction at a glance.
But regretful greedy (simulated min-cost flow) also works.
https://www.luogu.com.cn/article/2ensxnz4 ↗
Code:
https://www.luogu.com.cn/paste/l0g3abms ↗
CF623B Array GCD#
Fun one.
The key realization: since you can’t delete everything, either the first or the last number survives.
So you only need the prime factors of those two numbers across six cases (plus one, minus one, unchanged).
Sieve them out first, then DP with each prime factor as the .
Let be the minimum cost at element with nothing deleted, currently deleting, or done deleting.
The transitions aren’t hard; see the code.
Once you get step one, the rest is routine.
https://www.luogu.com.cn/paste/d1zcnjfe ↗
CF521D Shop#
I remembered the approach but had misread the statement.
The order of operations is always assign, then add, then multiply.
For assignment keep only the largest per position, which converts assignment into addition.
Sort the additions descending, which converts them into multiplications.
Finally sort the multiplications descending and output the first .
https://www.luogu.com.cn/paste/9iffudq6 ↗
CF486D Valid Sets#
Inertia again: I saw the constraints and immediately wanted a two-dimensional DP state.
Since the constraints are so small, just enumerate each node, force it to be the maximum, and DP with it as the root:
which is essentially a knapsack merge.
https://www.luogu.com.cn/paste/xqad5b23 ↗
CF19E Fairy#
Took me forever to even understand the statement.
It asks which edges, when removed, leave a bipartite graph.
The criterion for bipartiteness is the absence of an odd cycle.
The answer is the intersection of all odd cycles that appear.
A dfs handles it.
https://www.luogu.com.cn/paste/edls0m5o ↗
P4161 [SCOI2009] Game#
https://www.luogu.com.cn/article/zmgkp11r ↗
AT_arc070_b ABC056D No Need#
The key here is that element is not dispensable exactly when the rest cannot build up .
First instinct: run a knapsack and then remove items one at a time — since a knapsack can be read as a polynomial, removal is dividing by a polynomial. Looking at my code, I instead optimized the DP with CDQ divide and conquer. The editorial has another approach that’s quite interesting: [[https://www.luogu.com.cn/article/o87199on ↗]]
my code: https://www.luogu.com.cn/paste/ds9v7cib ↗
AT_agc010_b AGC010B Boxes#
No ideas beyond difference arrays. Blew it, went to the editorial.
Half the editorials got details wrong, ugh. It’s a rather clever thinking problem. Each operation decreases the total by , so a solution exists only when is an integer.
Now look at the difference array: each operation does at one index and everywhere else. Let be the number of type-one operations at position . That gives the equation
which solves to and that settles the problem — just check that every is non-negative.
https://www.luogu.com.cn/paste/76krqu56 ↗ btw, I’m not quite sure how to reduce this problem to a general class.
AT_arc063_c ARC063E Trees and Integers#
Small brain-lapse. There’s an obvious construction: push all the initially weighted nodes into a priority queue, repeatedly pop the largest, and assign its unassigned neighbors that node’s weight minus one. Then check validity at the end.
https://www.luogu.com.cn/paste/ts26d0ak ↗
AT_agc004_c AGC004C AND Grid#
Nice construction. Noticing the border is never covered, you can construct the two grids like this:
###. ....#
#.... ####
###. ....#
#.... ####
###. ....#plaintextand then just color in the original grid’s cells.
https://www.luogu.com.cn/paste/oa3ylcch ↗
CF1051F The Shortest Statement#
It isn’t hard to see you should pull out a spanning tree first. The remaining non-tree edges touch at most 42 nodes; call those special. Run Dijkstra from each special node to get its distances to everything. For a query, first get the tree distance via LCA, then enumerate the special nodes and check whether forcing a path through one is shorter. Easy to implement. https://www.luogu.com.cn/paste/89h3fi2e ↗
CF1234F Yet Another Substring Reverse#
I got most of the way there but not all of it. The constraints immediately suggest bitmasks. But is large, which confused me. Analyzing calmly: what you actually need is two intervals with maximizing the popcount of . A high-dimensional prefix sum does it: for each character set, sum its answer with its complement’s. https://www.luogu.com.cn/paste/vi8s04gg ↗
P1989 Counting Triangles in an Undirected Graph#
Why is this idea so clever? One look at the constraint and it felt hopeless — I broke into a sweat and went to the editorial, only to find I’d written this problem shortly before retiring in high school (sigh). First, turn each undirected edge into a directed one, from lower degree to higher degree, breaking ties by smaller index. Then you can brute-force it. For each node , mark all its neighbors, then enumerate each neighbor , then enumerate each neighbor of and check whether is marked by ; if so, add to the answer. Why is the complexity fine? Consider the nodes one at a time: the complexity is each node’s in-degree times its out-degree.
If a node’s degree in the original graph is , its out-degree is certainly too. If its degree is , it only points to nodes of higher degree, of which there are at most , so its out-degree is also . For in-degree, consider each original edge : its contribution to the complexity is , and since as proven above, the total complexity is .
https://www.luogu.com.cn/paste/9g86u6as ↗
AT_agc033_c AGC033C Removing Coins#
I never thought in this direction. Silly me.
You only need the diameter length: each operation reduces it by 1 or 2, so compute the diameter and check it . You can also derive it with Grundy values.
https://www.luogu.com.cn/paste/9h9kwq6m ↗
AT_arc100_c ARC100E Or Plus Max#
My thinking got rigid: high-dimensional prefix sum at a glance, but then I didn’t see how to handle .
Looking at my code, you just track the largest and second largest while doing the high-dimensional prefix sum. Obvious in hindsight, and I still missed it. Remember the constraint is , so take a prefix maximum at the end. https://www.luogu.com.cn/paste/m1mn89hu ↗
AT_arc115_d Odd Degree#
The easiest observation is that an odd number of odd-degree vertices is impossible, so only even has an answer. Consider the tree case first. If you fix which vertices have odd degree, every tree edge’s inclusion is determined (work up from the leaves). Likewise, once you add some non-tree edges, the tree edges’ states are still determined. With vertices and edges in total, forcing vertices to odd degree gives ways, and then you merge across connected components with a knapsack. The hard part is analyzing the tree case first.
AT_arc122_d XOR Game#
For XOR problems there are only so many angles. Go from the high bit down. If the count of 1s at this bit is odd, the final answer is determined at this bit: you just need to find which 0-at-this-bit element to pair with which 1-at-this-bit element to minimize the answer, since the second player decides. A trie solves it. If the count of 1s at this bit is even, they pair up perfectly, this bit ends as 0, so split the numbers by this bit and continue at the next one.
AT_arc124_d Yet Another Sorting Problem#
Start with the unrestricted case where you may swap freely: link to to get a set of cycles, and a cycle of length needs operations to put every position in place. Each cycle is clearly independent. For this problem, a cycle spanning both halves also takes only operations. If all of a cycle’s nodes are on the left, you must add two edges to join it with some cycle (or single node) on the right, forming one big cycle. With cycles on the left, on the right, and cycles total, the answer is . The single-node case needs special handling.
AT_arc126_d Pure Straight#
First, is tiny, so bitmask DP. Now, how to design the state? Let be: considering position i, having fixed the values in state . For position i, if doesn’t appear in , you can take it — count how many elements of S are larger than it, since those must all be swapped with , contributing that much (i.e. the inversion count), then transition into the state containing .
Or you can skip : compare whether it’s better to move everything already chosen past i, or to move everything chosen later past i, and take the min. This counts as a DP with contributions computed in advance.
CF11D A Simple Task#
Hadn’t woken up.
The constraints say bitmask DP at first glance, and the key is forcing the smallest index as the start. Let be the number of paths covering the set with current endpoint ; the transition is then easy, just enumerate the neighbors of . Note that walking an edge back and forth, and each cycle being counted twice, means the answer is .
CF19E Fairy ↗#
Right direction, but I never nailed down the details. Getting old, can’t push through the properties any more qwq
CF165E Compatible Numbers#
Textbook high-dimensional prefix sum.
CF367E Sereja and Intervals#
Misread the constraints. Blew it.