2022 HDU 多校 2
A Static Query on Tree
把所有 A,B,C 集合中的点拖出来建虚树,然后在虚树上统计每个子树中 A,B 的点的个数和到根的链上 C 的个数即可。
复杂度 O((∑|A|+|B|+|C|)logn+nlogn) 。
B C++ to Python
去掉 std::make_tuple
即可。
C Copy
由于所有查询的位置和复制的区间都不超过 n ,暴力复制即可。操作次数为 20000n 。
D Keychains
只要能求出其中一个圆和另一个圆所在平面的两个交点,就只需要判断是否一个在圆内一个在圆外了。
首先任意求出两个平面的两个交点 C1,C2 ,然后可以求出交线的向量 L 。
接下来考虑求出 O2 在直线的投影。令 V1,V2 为两平面法向量,则 F=L×V2 为第二个圆所在平面上与直线垂直的一个向量。投影为 O2+F|F|⋅(F⋅(C2−O2)|F|) 。
然后后面那段其实就是点到直线距离,通过 √R2−d2 可以得到两个交点和投影之间的距离,再数乘 L|L| 即可得到两个点。
其实最难写的是第一部分,求两个交点。我开始想用三维的叉积解决后面发现有申必情况。于是改用土法炼钢——解二元一次方程组。代码写的很丑。
复杂度 O(1) 。
E Slayers Come
显然每个技能会干掉一个区间内的人。存下每个位置想要通过连锁反应消灭左右的人需要的最少 L/R 后,这个区间的左右端点都是可以二分(倍增)的。
然后问题就是给定若干区间,求出有多少种选择选择区间的方法使得所有点都被覆盖。
(一个 Edu G 的套路)可以容斥一下,变成钦定一些点,这些点不能被覆盖,求选出若干区间的方法。
用 dp[i] 表示第 i 个位置不能被覆盖,只考虑右端点在 1∼i 的区间的值。很显然,对于每个区间,它会使得 1∼l−1 区间中的 dp 值对 r 以后的转移的贡献乘 2 。容斥系数是 −1 ,即 dp[i]=−∑j≤idp′[j] 。
复杂度 O(nlogn) 。
F Bowcraft
自闭题,最后好像乱搞爆标了。
很显然,由于拿到一本书的时候的信息只有当前的等级,所以只要等级固定,决策就是固定的。
我们只要对于每个等级能够判断哪些技能书会被使用即可。
我开始的考虑是对于每个固定的 0≤a<A ,所有会使用的 b 一定是一个前缀,不妨设这个值是 ta 。很显然,随着 a 增加,这个值不降。
我先尝试计算 fn 为从 n 走到 n+1 期望需要买多少次书,即
fn=AB∑ti+∑0≤i<A∑0≤j<ti1∑tiA−iA(fn+jBSn−1)其中 S 为 f 的前缀和,即按是否成功分类讨论。
推推式子会发现
fn=A2B+∑0≤i<A(A−i)ti(ti−1)2B∑0≤i<aiti可以通过 dp 解决问题,设 dp[i][s] 表示考虑了前 i 个 a ,∑iti 的和是 s 时的最优分子,复杂度 O(KA2B2) 难以通过。
转而考虑什么时候一本书会被使用。可以发现,一本书可以使用当且仅当使用它后到达 n+1 的期望步数小于不使用,即:
fn>A−aAfn+A−aAbBSn−1fn>(A−a)baBSn−1b<aBfn(A−a)Sn−1题解做法:通过第二个式子可以发现对于一本书,它的 aB(A−a) 越小,它就越可能被使用。所以按照这个值排序后,会使用的书一定是一个前缀,对于每个前缀分别计算 fn 的值即可。可以发现新加入一本书对原来 fn 的分子和分母的影响都是固定的,所以可以直接 O(KAB) 解决问题。
但是我没有想到这一点!我顺着之前的想法,由第三个式子可以发现,如果确定了当前位置的答案 fn ,那么每个位置的 ti 就很容易被算出来。然后我就尝试二分了一下答案,通过二分的答案确定 t 算出一个答案后再和二分的答案比较,发现过掉了样例和测试数据。于是得到了一个 O(KAlogV) 的做法。但是我并不知道为什么这样二分是对的
后来思考了一下,发现这个二分答案的过程等价于二分选择权值前若干大的数。
代码中注意了之前的 t∈[1,B] 而后面 b∈[0,B−1] ,因此是向上取整。
G Snatch Groceries
太长懒得看,看最后一段和样例猜是按时间扫,输出第一个相交区间前的区间个数。
直接按左端点排序,然后找到第一个左端点小于上一个区间右端点的即可。很容易发现是对的。
H Keyboard Warrior
考虑通过 Hash 进行匹配。
把原串的开头一段和结尾一段字符拆出来,只考虑中间的字母计算 Hash 。
然后在操作的时候,如果加入的字符是原串开头字符且数量大于等于原串开头字符数量,那么把这个位置前面的字符对应的 Hash 值放入集合内。如果加入的字符是原串结尾字符且数量大于等于原串结尾的数量,那么就在这里查询一下 Hash 值减去原串中间部分的 Hash 乘上一个 base
的次幂。
复杂度 O(n+mlogk) 。其中需要计算 base
的等比数列前缀和。
I ShuanQ
有 PQ≡1(modM) 所以 M|PQ−1 。那么直接分解质因数并判一下 M 是否合法即可。
J Assassination
感觉难点在题意。题意是删除尽量少的边,使得之前的所有最大生成树都经过至少一条删除的边。
考虑 Kruskal 的过程,每个相同权值的边都是可以在求生成树的时候选择的。而想要所有生成树都经过至少一条删除的边,就可以考虑把某个权值的边中的一部分删除掉,使得原图被分成两个互不联通的子图。因为在原来求最大生成树的时候,一定会在这个选择这个权值的边时把两个子图连接起来,但是删除这些边后就做不到了。
因此把所有边按权值排序,并且把权值大于当前权值的边加入生成树并缩点起来。然后等价于给定一张边数不超过 100 的图,求最小割的大小。
对于一个连通块,考虑拿出度数最小的点,以这个点为源点并以所有其他同连通块的点分别做汇点跑点数次 dinic 求最小的最大流。如果最小度数是 k ,那么显然 dinic 的复杂度不超过 O(kE) (即使 EK 也就这个复杂度),因此总复杂度是 O(kVE) 。但是考虑每个点的度数的和是 2E−2 ,因此实际上 kV≤2E−2 ,所以复杂度是 O(E2) 的。又由于 ∑E=m ,总复杂度是 O(Em) 即 100m 级别,可以通过。
全局最小割有一个 S…-W… 的算法应该也可以做,但是没学过。
K DOS Card
用线段树维护区间内最小值、最大值、次小值、次大值、Al−Ar 的最大值、Al−Ar+Al′ 的最大值、Al−Ar−Ar′ 的最大值以及答案即可。
合并比较恶心,需要写的比较细心。
L Luxury cruise ship
对 365×31 之内的数跑个背包。如果 N 比较大,先给答案加上 N/365 再在这个范围内找所有和 N 同余的数更新答案即可。
复杂度 O(1) 。