「Solution Set」 JOISC 2023
我觉得 JOISC 的题都非常有水平!
P9329 [JOISC 2023 Day1] Two Currencies
简单题。因为每次尽量花银币,而且尽可能在银币花销比较小的花银币,所以整一棵主席树,二分。
复杂度 \(O(n\log n)\) 非常好。
P9331 「JOISC 2023 Day1」JOI 国的节日 2
喵喵题!但是我口齿不清说不明白!
看这个学会的。
首先正确的做法显著是按右端点排序,从左向右能选则选。
我们考虑记录两种贪心选出的数量相同的方案数,然后用总方案数减掉这个。
首先考虑总方案数怎么求。我们考虑先求出两两随便配对的方案,就是 \(\dbinom {2n} n\times n!\),这种你就已经选出了若干个有序的区间,但是区间并不保证 \(a_i\leq b_i\),所以需要除以 \(2^n\),所以总方案数是 \(\frac {(2n)!}{2^n n!}\)
思考正确贪心和假贪心选的区间的结构
假设正确的贪心选出的区间叫红区间,假贪心选出的区间叫蓝区间,同时选的区间叫紫区间,剩下没被选到的叫做黑区间。
对于每个红区间,都有如下性质:
- 相邻两个红区间的右端点之间不存在其他完整区间
同理对于每个蓝区间,相邻两个蓝区间左端点之间不存咋其他完整区间
我们将两种区间放在一起观察,因为要求数量相同,所以我们可以将红蓝区间两两配对。
然后考虑最终的结构:(图是从上面的题解偷的,但是原图是 JOISC 官方题解的)
然后能观察到以下性质:
- 对于一个红色区间,他配对的蓝色区间的右端点一定大于等于自己的右端点,他前一个的蓝区间的右端点一定小于自己的右端点。(从第一对区间开始考虑,第一对的红区间的右端点是最靠左的,所以第一个蓝区间的右端点在红区间的右端点的右边,然后再考虑下一个红区间,那么如果想让两两配对,第二个红区间一定要和第二个蓝区间有交,所以第一个蓝区间的右端点必须在红色区间右端点的左边,而第二个蓝色区间如果右端点小于自己的红色区间右端点,那么也不合法了)
- 对于每个黑色区间,其左端点必须和某个蓝色区间重合,
所以我们考虑设计类似这样的 DP:每次转移的时候考虑插入一对红色和蓝色的区间,并枚举在这对区间加入的同时加入的黑色右端点。
所以如果要 DP 的话,我们设计的状态要包含这样的东西
- 目前已经插入了多少个区间
- 能够插入黑区间的左端点有多少个
然后还要枚举插入多少个黑区间。
这个大概复杂度是 \(O(n^3)\) 的。
先不要考虑具体实现。考虑一下怎样压缩状态吧。发现“能插入黑区间的左端点的数量”是很浪费的东西,因为如果黑区间的右端点是完全没有限制的。如果能够用到这个性质就好了。
所以我们可以倒着插入每对红蓝区间,然后考虑左端点在加入区间附近(?)的黑区间的方案之类的。
这回认真的设一下状态:
设 \(f_{i,0/1}\) 表示已经插入了 \(i\) 个区间,当前的红蓝区间对是/否是紫区间。
然后考虑枚举 \(j\) 表示在插入新一对红蓝区间的时候将会插入多少对黑区间
再偷一张图
先考虑最复杂的一种情况
我们考虑插入的黑色区间左端点只能在第 \(i+1\) 对区间的红色右端点的右边
左端点就是图上标注出来的。
考虑右端点的方案数,所有的可行范围内有 \(2(i-2)+1\) 个点,也就是一开始有 \(2i-2\) 个区间可以插入右端点,第二个右端点就有 \(2i-2+1\) 个区间可以插入,第 \(j\) 个右端点就有 \(2i-2+j-1\) 种方案可以插入。所以右端点的方案数就是 \((2i-3+j)^{\underline{j}}\)
然后考虑左端点的方案数,我们发现可行区间内有 \(j+3\) 个点,但是两个蓝色的右端点应当相邻,所以可以视作 \(j+2\) 个点,其中有两个点是特殊的,所以左端点的方案数是 \(\dbinom{j+2}{2}\),这里是没有标号的,因为算右端点的时候已经有标号了。
所以一个转移方程就是 \(f_{i+j+2,0}+=f_{i,0}\times\dbinom{j+2}{2} \times(2i-3+j)^{\underline{j}}\)
然后另外三种情况的话比较好画,转移方程在下面
\(f_{i+j+2,0}+=f_{i,1}\times (j+1)\times (2i-2+j)^{\underline{j}}\)
\(f_{i+j+1,1}+=f_{i,0}\times (j+1)\times (2i-3+j)^{\underline{j}}\)
\(f_{i+j+1,1}+=f_{i,1}\times (2i-2+j)^{\underline{j}}\)
然后我们发现黑区间左端点在第一个红蓝区间前面的没有统计
所以在最后要枚举所有的 \(f_{i,k}\),统计一遍答案。
[JOISC 2023 Day1] Passport
假如我们只从一个点进入,我们可以直接线段树优化建图。
然后我们发现一个性质:只要能从一个点走到 \(1\),那么 \(1\sim i\) 所有点都是能走到的。到 \(n\) 同理。
于是我们可以先建反图,预处理 \(i\) 到 \(1\) 的最短路,\(i\) 到 \(n\) 的最短路。然后加起来会发现可能有重复的边,就是在 \(i\) 到 \(1\) 的时候走到了 \(i\sim n\) 里的点。
那么我们可以考虑以所有点为起点跑多源最短路,这样就像 dij 这样,消掉了可能的重复的边。
[JOISC 2023 Day2] Council
我们考虑把问题转化为去掉一个二进制数,再给一个二进制数 \(tmp\),求剩下的二进制数里和 \(tmp\) 与的最多的 \(1\) 的数量。
我们考虑先预处理 \(f_{S}\) 表示是否存在 \(S \subset a_i\),这个好像随便处理一下。
我们考虑再预处理 \(g_{i,S}\) 表示是否存在 \(s'\subset S,popcount(s')=i,s'\subset a_{k}\)
然后能直接求了。但是我们好像没有排除掉自己。我们可以转移的时候记录一下由谁可以转移,记录两个不同的就行。
洛谷评测机垃圾/fn/fn/fn
[JOISC 2023 Day3] Tourism
trick:求虚树覆盖联通块的大小:将关键点按 dfn 排序,所覆盖到的边数为相邻两个关键点之间的边数和除以二(假设第一个和最后一个相邻)
然后我们考虑回滚莫队,先把所有关键点弄下来按 dfn 排序,然后删掉点的时候就用链表计算贡献。
完事了就、
[JOISC 2023 Day3] Chorus
好题好题。
我们考虑怎样判断一个序列能不能唱。因为如果分的歌曲数量越多,是越容易组成队伍的。如果分的歌曲数量少于 \(K\) 的话,那随便拆几个就行了。
所以判断我们是会了,我们考虑怎样设计 DP 状态。
\(f_{i,j}\) 表示前 \(i\) 只母河狸,总共唱了 \(j\) 首歌的最小代价。显然的是一首歌肯定是由连续的几只母河狸和连续的几只公河狸组成,而如果存在公河狸在母河狸前面,就需要把它换到后面去。所以设 \(cnt_i\) 表示第 \(i\) 只母河狸前面有多少只公河狸。假设第 \(k\) 只母河狸到第 \(i\) 只母河狸要组成一首歌,对于任意一个母河狸 \(l\),如果 \(cnt_l\geq k\),那么就需要把多出来的这些公河狸都扔到后面去。否则不用管,后面需要匹配的公河狸是不用动的。
所以说了半天,DP式子是 \(f_{i,j}=\min\limits_{k=0}^{i-1} {f_{k,j-1}+\sum\limits_{l=k+1}^i \max (0,cnt_{l}-k)}\)
然后我们感性理解一下啊。就是越多的歌曲数目代价总是越小的。所以我们考虑 wqs 二分。。。。
然后我们考虑去求这个式子。
然后不会了正确的做法是求助伟大的红日
我们考虑设 \(pos_i\) 表示第一个 \(cnt_j\geq i\) 的位置 \(j\)。
假如转移的时候 \(pos_j>i\),那么就直接转移就行。
否则就是 \(f_{i}=\min f_{k}+sum_{i}-sum_{\max(pos_k,k)}-(i-\max(pos_k,k))\times k\)
然后这个可以随便斜率优化一下。然后就能做了。
[JOISC 2023 Day4] Bitaro's Travel
发现如果需要连续的调转方向的话,那么一定是另外一侧的距离大于之前走过的所有距离之和,才会调转方向,所以如果想转弯的话,那么最多会转 \(\log V\) 次,所以我们可以寻找每次它在什么地方转弯。
这个可以二分答案,每次二分一下到哪里就行。
剩下的摆了