THUPC2022决赛题解
简单的卡牌游戏
发现数据范围非常小,四种花色,每一种花色(已经打出的牌)一定构成一个连续段,且一定包括数字 $7$ 。
也就是说,每一种花色的卡牌只有 $50$ 种状态,总共只有 $6250000$ 种状态。
每个状态最多连出 $8$ 条边,且状态间构成有向无环图,于是可以直接记忆化搜索。
pmrmscxip
$a_{i+1}=b_{a_i}$ 即为指定每一个数的后继,又因为 $b$ 是一个排列,所以一个合法的连续段对应置换环上的一段链。
一次修改只会影响 $O(1)$ 个极长连续段,所以可以考虑维护极长连续段。
一个极长连续段包含 $x$ 的必要条件是该连续段所属的置换环包含 $x$ 。
将置换环展开成链,那么一个极长连续段可以表示为一个四元组 ${L,R,P,W}$。
其中 $W$ 是在原序列中的长度, $P$ 是在原序列中的位置, $L,R$ 是在(展开成链后的)置换环中的位置。
那么查询即为求在所有 $l \leq P \leq r,L \leq p \leq R$ 的连续段中, $W$ 的最大值(左右端点处的连续段可能不完整,需要特判)。
(查询变量小写字母,连续段变量大写字母, $p$ 是 $x$ 在其置换环中的位置)。
那么外层线段树,内层平衡树可以在 $O(n \log^2 n)$ 时间和 $O(n \log n)$ 空间内解决问题(外层实现直接区间修改)。
拯救还是毁灭
(参考百度贴吧讨论贴中结论)
答案上界为 $2n(n-1)$ 。
首先在目标矩阵的基础上,每个位置循环右移一格,再循环下移一格。
这样的话行交换和列交换都至少要 $n(n-1)$ 次(证明就是考虑每一行数的集合以及排列的置换环理论)。
然后从上到下一行一行的归位,最后一行交换 $n-1$ 次,其它每一行交换 $2n-1$ 次。
最后一行方法显然,所以只需要讨论前面的行如何归位即可。
假设这一行中归位后的数为 $i*n+1$ 到 $i*n+n$ ,并且把它们在表中的位置找到。
如果 $i*n+x$ 的位置是格子 $(z,y)$ ,那么点 $x$ 向点 $y$ 连边。
因为有 $n$ 个点 $n$ 条边,所以一定有环,然后分别归位不在环上的数和在环上的数(注意顺序)。
对于不在环上的数:
按照拓扑序,每一个用 $2$ 次交换归位,先归位行(挪到最下面),在归位列(同样注意顺序)。
因为按照拓扑序归位,所以不会把之前已经归位的数打乱。
对于在环上的数:
先整体归位行,在整体归位列(前者因为去除了环外点的影响,不会出现一列两个数的情况,而后者相当于最后一行的方法)。
一定有环,所以容易证明归位一行的交换次数严格小于 $2n$ 。
高性能计算导论集群登录密码复杂性策略
$dp_{i,j}$ 表示前 $i$ 个数,状态为 $j$ 的方案数(状态包括最后一位以及递增递减/重复序列的长度)。
但是 $L,R$ 的范围高达 $10^9$ ,所以要想办法加速这个递推式。
然后递推式加速我目前只会 $O(k^3)$ 的矩阵乘法。这题的状态数 $k$ 大约有 $3600$ ,矩阵乘法肯定不行。
据说 Berlekamp-Massey 算法可以解决这个问题。
倍增路径
$dp_{i,j,k}$ 表示目前走到点 $i$ ,在第 $j$ 轮操作,路径边权和余数为 $k$ 的最大分数,转移显然。
注意 $k=0$ 时更新答案以及进入下一轮,以及刚开始时虽然 $k=0$ 但是不能直接进入下一轮。
riabq
序列分块,假设 $1$ 代表左边零散块, $2$ 代表中间整块, $3$ 代表右边零散块。
$S(1,1)+S(3,3)$ : $f_{x,y,z}$ 表示第 $x$ 块中 $a_w \leq a_y,w \leq z$ 的 $w$ 个数,修改时枚举 $j$ 计算 $b_j$ 增加次数。
$S(1,3)$ :块内排序,修改时枚举 $j$ ,双指针扫描计算 $b_j$ 增加次数。
$S(2,3)$ : $f_{x,y}$ 表示前 $x$ 块中 $a_z \leq y$ 的 $z$ 个数,修改时枚举 $j$ 计算 $b_j$ 增加次数。
$S(1,2)$ :相当于 $\sqrt{n} \times n$ 的平面上 $O(n \sqrt{n})$ 次单点修改与 $O(n)$ 次矩形求和,用这题中做法。
$S(2,2)$ :修改时打差分标记,查询时枚举 $i$ 所属的块,计算两块间累加次数和每次累加的增加次数,注意最后一块特殊处理。
匹配
明显每个位置独立,位置之间互不影响,每个位置取 $0$ 和取 $1$ 的代价容易计算。
但是有一些串强行不能取,而且不能取的串长度都是 $L$ 。
把这些不能取的串插入到字典树中,然后设 $dp_i$ 表示从字典树的 $i$ 号点往下走的最小代价。
然后考虑往左还是往右(就是对应位置取 $0$ 还是取 $1$ ),注意处理子树为空的情况。
rsraogps
首先对于一个固定的右端点 $r$ ,左端点 $l$ 从 $r$ 扫到 $1$ ,乘积发生改变的次数为 $O(\log n)$ 。
然后把询问按照 $r$ 从小到大排序,相当于扫描线+树状数组(或线段树)维护,时间复杂度 $O(n \log^2 n+q \log n)$ 。
对于右端点 $r$ ,乘积发生改变的位置可以从右端点 $r-1$ 的位置继承下来,在加上 $r$ 自己。
因为三种价值对应的信息都能合并,且具有一定意义上的单调性。
然后将序列中 $\log n$ 个位置分一块,查询区间 $[l,r]$ 时要求 $[l',r']$ 的价值之和,分 $r,r'$ 是否在同一块内两种情况分别计算。
不在同一块内的处理:注意到长度为 $\log n$ 的连续段对应改变位置的并集大小依然只有 $O(\log n)$ 。
用同样的方法找出这些位置,然后用之前的处理方法。
在同一块内的处理:假设这一块为 $[x,y]$ ,令 $r$ 从 $x$ 到 $y$ 扫描,动态维护 $r' \in [x,r]$ 的信息。
$$f(l)= \sum_{i=l}^r \sum_{j=max(i,x)}^r val(i,j)$$
那么查询就是函数 $f(l)$ 单点查询。
由于改变位置的并集大小只有 $O(\log n)$ 所以 $f(l)$ 其实是 $O(\log n)$ 个一次函数“拼接”而成的折线,直接暴力修改。
时间复杂度 $O(n \log n+q \log n)$ 。
德州消消乐
大模拟。

浙公网安备 33010602011771号