ptz22w 部分题解
Day 1. Kyoto U Contest 2
F. Flatland Currency
考虑整个问题其实就是要背包,特殊性质是每个物品的权值 \(\leq 4\)。
先把相同权值的合并,然后每一类是一个凸函数,于是可以逐个卷积合并,复杂度是 \(\mathcal O(n\log n)\)。
题解做法是如果按照模 \(12\) 分类,则每一个都是凸函数,枚举每个模 \(12\) 之后的值之后可以凸函数卷积合并,这样是 \(\mathcal O(12\cdot 6\cdot 4\cdot 3\cdot n)\) 的。
H. High Powers
考察多项式 \(f(x)=(x-a)(x-b)(x-c)\),不难发现,这就是
并且有 \(f(a)=f(b)=f(c)=0\),于是将整个问题降幂,降幂之后的子问题满足 \(0\leq n,m\leq 2\),这些问题的答案都是平凡的。
J. Juggler’s Trick
先考虑如果已知序列怎么做:我们对每个前缀求答案。
考虑一下转移,相当于对每个能被选完的区间 \([l,r]\) 做贡献 \(f_r\gets f_l+r-l\)。
考虑一下什么样的区间是能被选完的,首先一个必要条件是 \(r+b|len\),且 \(\frac{r-b}{r+b}len=S_r-S_b\)。注意到如果满足这个条件则我一定可以用中值定理找到其中一个长为 \(r+b\) 的合法区间,于是这也是充分条件。
然后考虑一下怎么确定颜色,我们依然对每个前缀求答案,但此时能转移当且仅当满足一个偏序关系,对这个跑个分治动态二维偏序即可。
L. Lion and Zebra
把 \(u\) 提为根,然后注意到有一类状态是重要的:当前点一路走到 \(v\) 且过程中每次 \(d\gets d-2\),换句话说,\(d\) 在当前点的子树中。记这个状态的答案为 \(f_v\),则有转移:
其中 \(dis_u\) 为到子树最远的叶子的长度,\(d_u\) 表示走到这个点的时候的 \(d\)。
其中第一个和式相当于枚举一个儿子走下去然后考虑 B 是否在子树里,第二个相当于直接往父亲 run,这个柿子成立因为我最优方案中如果 B 不在子树一定会直接 run 子树,往回 run 同理。
现在来考察两个柿子的大小关系,注意到:
这直接导出:
换句话说,我如果走到一个不是长儿子的点且 B 就在其子树中,则我下一步会直接 run 到当前点的长儿子里去。
于是分类讨论一下发现当 \(d\geq 3\) 的时候我一定会走向长儿子,且 B 也会在最长的儿子里恶心我。而 \(d\leq 2\) 的时候的情况是简单的,于是模拟一下就做完了。
Day 2. KAIST Contest + KOI TST 2021
没一道能写的.jpg
D. Two Bullets
相当于给一张拓扑图,然后每次删两个度数为 \(0\) 的点,求最小次数。这个问题叫 two-processor scheduling,某篇论文指出答案可以按照如下方式构造:
- 维护一个拓扑序,每次加入一个入度为 \(0\) 的点。如果有多个则按照如下方式选择:写出所有能一步走到它的点的拓扑序,并按照递减顺序排序:
然后选取 \(N(v)\) 字典序最小的一个。
- 倒着构造答案,每次选取没有出度的点中拓扑序最大的两个
然后考虑一下怎么维护这个过程,先把整个图做反链划分,容易发现后面的反链的下标一定大于前面的,于是只用考虑同一反链内部的顺序,发现可以用线段树简单维护,于是做完了。
复杂度 \(\mathcal O(n\log^3 n)\)。
题解指出,答案同时也等于 \(n\) 减去反链的最大匹配的大小,这可以做如下理解:
- 首先把每次拿出来的东西匹配则构成一个匹配
- 其次考虑任意一个匹配,容易证明一定存在一种调整方式使得匹配大小不变且是一种满足条件的匹配
于是能选出的对数就是最大匹配的大小,于是根据某篇论文的结果,可以在 \(\mathcal O(n\log\log n)\) 的时间内求出答案。题解声称存在很简单的 \(\mathcal O(n\log n)\) 做法,但我觉得他大概率是在演。
H. Endless Road
考虑如果某两个区间有包含关系则较小的那个一定在较大的前面被删除,于是可以直接干掉较大的,剩下的所有区间一定单调,于是每次修改修改的一定是一段区间,于是用线段树维护这个修改,同时每次加入没有子区间的区间,它一定是右端点的前缀最小值,于是做完了。
I. Streetlights
考察如果询问很少怎么做,把所有 pair 分成有一边不确定高度和两边高度都确定,第一类可以每次询问暴力扫所有不确定高度的来求答案,\(\mathcal O(q^2)\)。第二类考虑所有可能的区间如果相交则一定有一边一定不行,于是第二类只有包含和相离两种关系。
于是对第二类区间建树,则考虑每个不确定高度的位置,它的贡献是 ban 掉某条链,用数据结构维护即可 \(\mathcal O(q\log^2 n)\)。
于是把这个套一个分治,考虑一下每一层不用真的建出整棵树,而是把所有修改能到的节点拿出来建虚树。于是树的大小是 \(\mathcal O(len)\) 的,也就是说每一层的本质的区间的个数是 \(\mathcal O(len)\) 的,把这些区间拿出来暴力建下一层的树复杂度就是对的,现在复杂度是 \(\mathcal O(q\log^3 n)\),因为每个询问都在每一层对应一个修改,但是查询个数只有 \(\mathcal O(q)\) 个,于是把树剖换成树上差分即可 \(\mathcal O(q\log n)\),但是分治建树需要线段树维护区间最大值,于是 \(\mathcal O(q\log^2 n)\)。
Day 3. Kazakhstan Contest
A. Two Trees
对第一棵树边分治,在第二棵树上建虚树 dp 即可。
B. Tarzan Jumps
首先考虑一下每个点一步能走到的点是哪些,发现是单调栈里被他弹掉的点和最多一个没被他弹掉的点。
注意到一个关键性质是答案不超过 \(2\),于是只用考虑答案为 \(1\) 的情况。那无非是两种情况:经过修改的点,不经过修改的点。
-
如果不经过修改的点,则原来的两个点一定在两边都被被修改的点弹掉了,换句话说两个点一定在前后缀单调栈里。然后发现 min-max 的所有贡献一定经过最小/最大的,而 min-min 的贡献是一个归并排序的过程,只有 \(\mathcal O(n)\) 对,这些暴力做即可。
-
如果经过修改的点,则相当于它和前缀/后缀单调栈中的某个元素相连了。而注意到这个点的取值只会是被他弹掉的点 \(\pm 1\)(因为没弹掉的放在后面更优),于是这个点也只有 \(\mathcal O(n)\) 种取值,用线段树维护即可。
总复杂度 \(\mathcal O(n\log n)\)。
C. Inversions
考虑一下 \(k\) 次方的组合意义:相当于依次选 \(k\) 个逆序对出来,而注意到大部分元素都没在任意一次当中被选到,这些元素的贡献是容易计算的,于是 dp 出 \(n\leq 2k\) 的方案数然后容斥出长为 \(i\) 的极小单位的贡献 \(g_i\),最终答案就是:
分段打表维护阶乘即可 \(\mathcal O(k^3)\),FFT 加速即可 \(\mathcal O(k^2\log k)\)。
E. Mountains
考虑直接 dp 有多少种本质不同的 dp 数组,注意到一个 dp 数组合法当且仅当满足单调性且所有元素不超过 \(k\),于是这就是一个 LOJ6677 的异时空同位体。
G. Maximal Subsequence
考虑整个问题是个最小割,于是转最大流之后相当于要选出最多个不交 LIS。
那考虑先求出 dp 数组,每个 LIS 一定是每种 dp 各一个,而相同 dp 间是反链,于是不难推断出一种策略是每次选字典序最小的 LIS,用各种手段维护一下即可。