rank | solved | A | B | C | D | E | F | G | H | I | J | K |
---|---|---|---|---|---|---|---|---|---|---|---|---|
4 | 9 | O | O | Ø | O | O | . | ! | Ø | O | Ø | O |
HDu5129 Yong Zheng's Death 题解
AC 自动机
模板
1 | namespace ACAM { |
基于变换合并的树上动态 DP
动态最大独立集
显然有 $dp(u,0/1)$ 表示点 $u$ 是否选,转移显然。
把答案拆成两部分,只选取轻儿子的 $dp$ 值 $g(u,0/1)$ 和本来的 $dp$ 值 $f(u,0/1)$。
对于点 $u$ 的重儿子 $v$,可以列出转移方程:
$$
f(u,0)=g(u,0)+max(f(v,0),f(v,1))=max(g(u, 0)+f(v, 0), g(u,0) + f(v, 1)) \
f(u,1)=g(u,1)+f(v,0)
$$
定义一个广义的矩阵乘法,加法改为取 $\max$,乘法改为加法,则有转移矩阵:
$$
\begin{bmatrix}
g(u,0) & g(u, 0) \
g(u,1) & -\infty
\end{bmatrix}
\begin{bmatrix}
f(v,0) \
f(v,1)
\end{bmatrix}
=
\begin{bmatrix}
f(u,0) \
f(u,1)
\end{bmatrix}
$$
这个 $dp$ 现在可以改成用树链剖分维护每个点只选取轻儿子 $dp$ 值的矩阵。
一个点的 $dp$ 值,可以通过从该点重链的叶子结点往上转移的方式得到。
对于修改操作,一个点所处的重链均不需要修改,只需要修改重链的链头的父亲,记录一下修改前后的链头变化,更新一下这个父亲的矩阵,再通过重链往上爬。
单次操作复杂度:$\mathcal{O}(8\log^2n)$。
2014 年 ACM/ICPC 北京现场赛
rank | solved | A | B | C | D | E | F | G | H | I | J | K |
---|---|---|---|---|---|---|---|---|---|---|---|---|
3 | 10 | O | O | O | O | Ø | O | ! | O | O | Ø | O |
树状数组上的黑科技
参考博客 树状数组黑科技讲义。
区间加 区间询问
令 $b_i=a_i-a_{i-1}$,那么 $a_x=\sum_{i=1}^x b_i$。于是,对于区间询问有
$$
\sum_{i=l}^r a_i = (r-l+1)\sum_{i=1}^{l-1} b_i + (r+1) \sum_{i=l}^r b_i - \sum_{i=l}^r i \cdot b_i
$$
分别在树状数组数组上维护 $b_i$ 和 $i \cdot b_i$ 即可。
权值树状数组二分第 $k$ 大
树状数组对应一棵没有右儿子的权值线段树,权值线段树上二分时,只需要和左儿子比较,因此权值线段树上二分可以扩展到树状数组上。
更新时,正常单点更新即可;二分时,每个点的权值对应线段树上结点的权值。
树状数组上结点 $p$ 的左儿子为 $p - lowbit(p) / 2$,右儿子为 $p + lowbit(p) / 2$。
注意边界上的细节,数组大小建议放大到 $2$ 的幂次。
Codeforces 1181D Irrigation 题解
2019 计蒜之道复赛 A 外教 Michale 变身大熊猫
题面
给定一个长度为 $n$ 的序列 $a$,等概率选择一个他的最长上升子序列,求每个位置被选到的概率。
其中 $1 \le n \le 10^5$。
分析
考虑如何求最长上升子序列的个数,令 $dp(i)$ 表示最长上升子序列最后一个数为 $i$ 时的长度和方案数二元组。
两个二元组合并时,若长度相同,则方案数相加,否则选一个长度大的。
对于位置 $a_i$,在询问小于 $a_i$ 的 $dp$ 信息和,将这个信息和的长度加一后,更新 $a_i$ 开始的后缀中每一个位置的信息。
树状数组加速即可。
回到原题。
我们对于每个前缀求出最长上升子序列的信息,和对应每个后缀的最长上升子序列信息。
每一个位置的概率的分母为总方案数,若其前缀和后缀的 LIS 长度相加再加一等于总体的 LIS 长度,那么选择它的方案数就是两个部分方案数的乘积,否则方案数为 0。
Codeforces Round 564 题解
A Nauuo and Votes
B Nauuo and Chess
有 $n$ 个棋子,你要找一个最小的 $m \times m$ 的棋盘,放下这些棋子,要求两两曼哈顿距离大于下标之差的绝对值。
容易构造出沿着棋盘的上边和右边边缘放旗子即可。
C Nauuo and Cards
有 $n$ 张牌,编号为 $1$ 到 $n$,还有 $n$ 张空牌,现在你手上有 $n$ 张牌,桌上有 $n$ 张牌,你可以从桌上牌堆顶部摸一张,在放回一张到牌堆底部。
问最小操作次数,使得桌上按顺序为 $1,2,\dots,n$。
假如 $1$ 在手上,需要枚举出首先放几张空牌到桌上即可,其他情况类似讨论即可。
D Nauuo and Circle
给定一棵无根树,每个点编号为 $1$ 到 $n$,你现在需要将这棵树画在一个环上,满足环内不能有交叉。
固定根节点为 $1$,注意到一棵子树必须占据一段连续区间,一个点的儿子可以任意排列,每个儿子可以选择其度数个位置,容易 Tree DP。
E Nauuo and Pictures
给定 $n$ 个物品,每个物品有一个权值和是否被喜欢,做 $m$ 次操作,随机选择一个物品,其被选择的概率是其权值比上权值和,如果这个物品被喜欢则其权值加一,反之减一,求最后每个物品的权值期望。
注意到一个事实,每个物品的权值期望是正比于其权值的,因此只需要考虑权值为 $1$ 的情况即可。
相关证明 Codeforces Round #564 中文题解。
也可以理解,把一个物品拆成了 $w$ 个。因此可以看成两个巨大物品,喜欢和不喜欢两种总和。
对 $m$ 次操作做 $\mathcal{O}(m^2)$ 的 $dp$。
记 $f(i,j)$ 表示前 $i$ 次操作做了 $j$ 次加操作,$f(i,j)$ 可以转移到 $f(i+1,j+1)$ (选择一个喜欢的物品)或者 $f(i+1,j)$ (选择一个不喜欢的物品),除上概率。
最后,对于每个物品,根据其是否喜欢,在两种中权值的比重乘上前面计算的系数即可。
长链剖分
性质一
所有长链的长度和是 $\mathcal{O}(n)$ 的。
性质二
一个点的 $k$ 级祖先所在重链长度至少为 $k$。
$\mathcal{O}(n\log{}n)$ - $\mathcal{O}(1)$ 在线询问 $k$ 级祖先
首先预处理出倍增数组,再预处理每个数的最高位在哪,再预处理每条重链的端点长度为 $l$,顶点往上走 $l$ 步和沿着重链走 $l$ 步是哪些点。
对于 $k$ 级祖先,令 $r=highbit(k)$,显然 $r>k-r$,用倍增数组将询问点向上跳 $r$ 步到 $y$ 点。
由性质二,$y$ 所在链长大于等于 $r > k - r$。
最坏情况下,$y$ 就是一个重链顶点,由于其预处理了往上走至少 $r$ 步的点,因此可以直接回答,否则重链顶点在 $y$ 到答案的路径上,显然也可以直接回答。
第二种情况,$y$ 的重链端点是答案的祖先,那么显然 $y$ 和答案在一条重链内,也可以直接回答。
$\mathcal{O}(n)$ 统计每个点子树中以深度为下标的可合并信息
重儿子继承父亲的信息,由于信息是以深度为下标,因此只需数组指针移位。
轻儿子暴力将信息与父亲合并。
复杂度是 $\mathcal{O}(\sum\text{重链长度})$,即 $\mathcal{O}(n)$。