OI Contest Records ep.1
收录各大 OI 比赛试题的做题记录。
1. Kinoman
Source: POI 2015 First Stage
枚举 \(r\) 考虑维护对应 \(l\) 的答案。
只需要维护上一个种类相同的位置,支持区间加,区间 max 即可,容易使用线段树维护。
\(O(n\log n)\),Submission。
2. Toilets
Source: JOISC 2016 Day 2
并非很难。
F 比 M 要自由很多,于是 set F 为 \(1\),M 为 \(-1\),那么后缀和就该 \(\ge -1\)。
据此处理出整体后缀和即可判断有无解,接下来考虑最小化。
由于不满度取的是 \(\max\),其实基于贪心会发现我们一定会把后面的 M 提到第一个,这样一定最优。
然后就发现求答案等价于求最小后缀和,把后面的 M 挨个甩到前面去就行。
\(O(\sum |S|)\),Submission。
3. Territory
Source: JOI 2016 Final
有参考代码。
可以首先模拟出第一轮每一个 \((x_i,y_i)\),接下来考虑怎么做。
模拟得到最终的向量 \((\Delta x,\Delta y)\),那么令 \(x_i=x_i'+t\Delta x,y_i=y_i'+t\Delta y\),取 \(x_i'\in[0,\Delta x)\),于是我们将 \((x_i,y_i)\) 转化到 \((x_i',y_i')\),每个点可以对应的 \(t\) 恰是一段区间 \([t_m,t_m+k-1]\)。
枚举左下端点 \((x_i,y_i)\),对 \((x_i+1,y_i),(x_i,y_i+1),(x_i+1,y_i+1)\) 对应的 \(t\) 分别做区间求交即可得到答案。
时间复杂度 \(O(n\log n)\),Submission。
细节:
- \(x_i=\Delta x-1\) 时,需要注意此时对应的 \((0,y_i-\Delta y)\),减掉的原因是对应求 \(t\) 时的坐标转换,记得对应的 \(t\) 区间也需要整体相减。
- \(t\) 可以为负数,set 交区间初始左端点要设成 \(-n\) 而非 \(0\)。
- 对于 \(\Delta x<0\) 需要对第一轮的 \(x_i\) 做取反,\(\Delta x=0\),则交换 \(x_i,y_i\),\(\Delta x=\Delta y=0\),那么只需跑一轮,set \(k=1\),\(\Delta x\) 为任意非零数即可。
4. Triumphal arch
Source: POI 2013 Second Stage Day 1
二分答案 \(k\),那么问题转化为判定。
不能直接贪心的原因是可以把上面的操作省给下面。
令 \(f_u\) 表示 \(u\) 需要上面援助多少次操作才可以全部防住,那么有转移:\(f_u=son_u-k+\sum_{v\in son(u)} \max(f_v,0)\),其中 \(son_u\) 是儿子个数。
DP 一次是 \(O(n)\) 的,于是做到 \(O(n\log n)\),Submission。
5. Игра с таблицей
Source:ROIR 2024 Day 1
简单题,由于 \(h,w\) 很小,于是有 \(O(2^{h+w})\) 的暴力。
枚举 \(2^h\) 后,对 \(w\),会发现问题变成了一个值域巨大的 01 背包,折半搜索即可做到 \(O(2^{h+w/2})\)。
毛估估一下发现过了,Submission。
6. Выбор столицы
Source: ROIR 2024 Day 1
考虑定根时怎么做。
二分答案,考虑 check 答案 \(x\)。
有一个素质很高的贪心,选择最深的点 \(u\),选取他的 \(x-1\) 级祖先 \(a\),将 \(1\) 与 \(a\) 连边,那么我们是不是 \(a\) 的子树就全部下班了。
用线段树维护全部点到 \(1\) 的距离,那么问题可以规约成子树减,整体维护最大值,上个 dfn 序线段树就好,子树减而非子树覆盖便于撤销。
于是单次就可以做到 \(O(k\log^2 n)\)。
换根的时候,只需要考虑怎么维护距离,以及求解 \(k\) 级祖先。
维护距离是简单的,大概就是一次子树减,一次子树补加,三次区间操作就好。
\(k\) 级祖先,则分情况讨论:
- 在 \(r\) 子树内,那么直接跳就好。
- \(r\) 子树外的点 \(u\) 求 \(k\) 级祖先,则首先求出 \(r,u\) 的 LCA,然后 \(u\) 跳到 LCA 再跳到 \(r\),中间维护一下倍增就行。
求 \(k\) 级祖先就是单次 \(\log n\) 的,足矣。
这样就可以做到 \(O(nk\log^2n)\) 了,理论能过。
当然可以更优,有一个性质是如果我保留父亲的方案,那我再坏也是 \(ans_f+1\),于是可以只 check \(ans_f\pm1\)。于是单次就是 \(O(k\log n)\) 的了,总时间复杂度 \(O(k\log^2n+nk\log n)\),Submission。
7. XOR 최대
Source: KOI 2024 Round 2
首先第一感是取第一个 \(1\) 出现的位置,记为 \(p\) 然后取 \([p,n]\) 为第一个区间。
第二个怎么取,考虑填充尽可能高位的 \(0\),记下一个 \(0\) 连续段的长度是 \(l_1\),第一个 \(1\) 连续段的长度是 \(l_2\),那么我们可以构造 \(\min(l_1,l_2)\) 来填 \(0\) 连续段。
而后面的 \(0\) 无法任由我们改变了,这样做到 \(O(n)\),Submission。
8. RMT
Source: CCC 2017 S5
直接序列分块,查询就被秒了,考虑修改。
不难发现对于每个块,一次位移只会导致一个元素加入删除,于是维护每个 loop 上哪些区间属于哪个块,单次位移只需要 swift 一下就行。
对于散块维护一下 swift 长度即可直接提取,\(O(n\sqrt{n})\),空间复杂度线性,Submission。

浙公网安备 33010602011771号