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)$ 。

德州消消乐

大模拟。

posted @ 2022-07-01 17:59  Miracle_Creater  阅读(768)  评论(3)    收藏  举报