刷(shui)题记录 2021.11

[JOISC2020] 首都

\(\Rightarrow\)原题链接

可以想到,答案实际上是选择的城市数量减去 \(1\)

选择的城市的所有城镇要连成一个联通块,那么对于属于同一个城市中的两个城镇 \(x,y\) ,假如选择了这个城市,那么路径 \((x,y)\) 上所有的城镇所属于的城市都要被选择。因此可以建一个新图,对于路径 \((x,y)\) 上的所有除 \(x, y\) 的点 \(p\) ,建边 \(C_x\rightarrow C_p\) 。那么答案就等于新图中最小的没有出度的强连通分量的节点个数。但是这样建边的边数为 \(O(n ^ 2)\) 的。

首先可以想到用树链剖分+线段树优化建图优化,但是边数依然是 \(O(n \log_2^2 n)\) 的,会 \(\verb|MLE|\)

可以用类似的思路+倍增,对于原图的点 \(u\) 其建边方式如下:

\[(u,0) = C_{\mathrm{fa}_u}\\ \mathrm{for}~i > 0,~(u,i)\rightarrow (u,i-1), (u,i)\rightarrow (\mathrm{fa}_{u,i-1}, i - 1) \]

其中 \((u,i)~(i>0)\) 表示新图中的一个节点。

那么对于任何一组 \((x,y)\) ,其连边方式就很明显了。

[AGC043-B] 123 Triangle

\(\Rightarrow\)原题链接

对于第二行开始的所有 \(f\) 值,都是 \(0/1/2\) 中的一个,可以首先将第一行的 \(f\) 都减去 \(1\) ,让所有的 \(f\) 的值域相同。

考虑首先判断答案的奇偶性,可以发现奇偶性数组 \(g(i,j)=g(i-1,j)\oplus g(i-1,j+1)\)\(\oplus\) 表示异或)。

那么可以得到

\[g(N,1) \equiv \bigoplus_{i=1}^N \binom{N-1}{i-1} g(1,i) \pmod{2} \]

在模 \(2\) 的情况下,有 \(\binom{a}{b}=[a~\mathrm{and}~b = b]\)

接下来判断 \(g(N,1)=0\) 情况下的答案。可以想到如果存在至少一个 \(1\) ,那么答案必然为 \(0\) ,因为 \(2\) 遇到 \(1\) 都会变成 \(1\)

接下来只要判断只有 \(0/2\) 的情况,显因为 \(2-2=0,|0-2|=|2-0|=2\) ,这个很像 \(g(i,j)\) 的计算过程,设新的数组是 \(h\) ,那么就有:

\[h(N,1) \equiv \bigoplus_{i=1}^N \binom{N-1}{i-1} [f(1,i)=2] \pmod{2} \]

如果 \(h(N,1)=1\),那么最终答案就是 \(2\),否则就是 \(0\)

[ARC119-D] Grid Repainting 3

\(\Rightarrow\)原题链接

先建个图,对于矩阵中 \(s_{i,j} = \verb|R|\) 的位置,在图上建立 \(i \leftrightarrow j+N\)

矩阵上选择一个位置进行操作实际上就是对于图中一条边,选择其中一端。

考虑白块个数的计算方式,参数显然是被覆盖为白色的行数和列数,设其分别为 \(a,b\) ,可以得到:

\[\mathrm{ANS}(a,b) = aM+bN - ab \]

考虑我们在新图中的选择方案,可以发现实际上就是找到一颗 \(\mathrm{dfs}\) 树,由底向上“操作”,然后舍去根节点,也就是说,对于一个联通块,我们必须舍去一行或者一列。这里稍微解释一下“操作”是什么意思:对于一条在 \(\rm dfs\) 树上的边 \(x\leftrightarrow y\)\(x\) 为父亲),如果 \(y\) 是行节点,那么就是将 \((y, x - N)\) 所在的行覆盖为白色;如果 \(y\) 是列节点,那么就是将 \((x - N, y)\) 所在的列覆盖为白色。

枚举多少个联通块舍去了一行,得到最优的参数 \(a,b\),然后对于每个联通块,选好根节点是行节点还是列节点,然后 \(\rm dfs\) 得到方案。

[LG-P4437] [HNOI/AHOI2018]排列

\(\Rightarrow\)原题链接

对题目进行转化,对于任意一个 \(i\) ,建立节点 \(a_i \rightarrow i\) ,可以认为原问题变成了选择一个 \(0 \cdots n\) 的排列 \(P\) ,满足儿子节点 \(u\)\(P_u\) 大于父亲节点 \(v\)\(P_v\) ,而我们要令 \(\sum_{i=1}^n p_i w_i\) 最大。这个很像某道题,但是数据规模更大,用并查集和优先队列优化一下。

[LG-P7026] [NWRRC2017]Hidden Supervisors

\(\Rightarrow\)原题链接

首先考虑如果没有不确定祖先的的点,最终答案怎么求,显然可以按深度从大到小考虑,如果一个节点 \(u\) 存在儿子节点 \(v\) 没有被选择,那么就选择 \(u\)\(v\) 作为一对。可以发现,如果存在两种最优方案,其中一种选择了根节点,另一种没有选择根节点,那么这种算法会选择不选根节点的那种。

接着考虑原题。我们要进行的操作就是将森林中每棵树的根节点(除了节点 \(1\))都选择一个往上的节点。首先对于每棵树都跑一遍上面提到的算法,接着分类思考一下:

\(T_u\) 是某棵树 \(T\) 的根节点。

  • 当前森林中不存在 \(T\) 之外的没有选择的节点,那么这时候可以直接将 \(T_u\) 连到 \(1\)
  • 当前存在 \(T\) 之外的没有选择的节点:
    • \(T_u\) 已经被选择,那么这时假如改变方案,使 \(T_u\) 选择这个在 \(T\) 之外的节点,那么对于 \(T\) 中的方案的贡献,至少会减少 \(1\) ,一定不会更优,因此 \(T_u\) 一样直接连到 \(1\)
    • 显然可以让 \(T_u\) 连接到这个节点就行了,匹配数 \(+=\ 1\)

这样就能得到算法了,首先将所有选择了 \(T_u\) 的树都连到 \(1\) 。对于剩下的,为了尽量增加匹配数,可以按没有选择的节点个数由大到小考虑。

[LG-P6071] 『MdOI R1』Treequery

\(\Rightarrow\)原题链接

首先用 \(\verb|ST|\) 表得到任何一个区间的 \(\rm LCA\) ,方便接下来的操作。

\(T_u\) 表示以 \(u\) 为根节点的子树的所有节点。

接下来大力分类思考:

  • \([l,r]\subset T_u\) :那么答案显然是 \(\mathrm{dis}(p, \mathrm{LCA}(l,r))\)
  • \([l,r] \not \subset T_u\)
    • \([l,r] \cap T_u \not = \empty\),那么答案显然为 \(0\)
    • \([l,r] \cap T_u = \empty\)
      • \(p \not\in T_{\mathrm{LCA}(l,r)}\),那么答案一样是 \(\mathrm{dis}(p, \mathrm{LCA}(l,r))\)
      • \(p \not\in T_{\mathrm{LCA}(l,r)}\),这时候首先要找到深度最小的,满足没有任何一个 \([l,r]\) 中的节点在其子树的节点 \(u\) ,这个东西可以用倍增跳。答案就是 \(\mathrm{dis}(u,p)+1\)

接下来只需要考虑怎么求出某棵子树 \(T_u\) 中编号在某个区间 \([l,r]\) 中的节点个数就行了。这相当于求出下面的问题:

\[Q(u,l,r) = \sum_{i=l}^r \left[\mathrm{dfn}(u)\leq \mathrm{dfn}(i) < \mathrm{dfn}(u)+|T_u|\right] \]

这时候显然有 \(Q(u,l,r)=Q(u,1,r)-Q(u,1,l-1)\) 。然后用可持久化线段树维护 \(Q(u,1,lim)\) 的答案就行了。

[ARC103-D] Distance Sums

\(\Rightarrow\)原题链接

考虑一条边 \((u,v)\) 其中 \(u\)\(v\) 的父亲,那么一定有

\[D_u - D_v = n -2|T_v| \rightarrow D_u = D_v - 2|T_v| + n \]

因为 \(D_u\) 互不相同,同时因为 \(D_u\) 最大的点一定是某一个叶子,\(D_u\) 最小的点一定是重心,因此按 \(D\) 由大到小考虑,直接由上面的式子求出父亲,然后 \(\verb|check|\) 一下根节点是否符合就行了。

[AGC007-D] Shik and Game

\(\Rightarrow\)原题链接

根据经验,可以认为最优方案一定是将 \(N\) 只小熊分成若干段,从左到右考虑,对于一段小熊,操作一定是首先从左到右依次激活,然后折返回最左边的小熊,然后从左往右收取金币,然后向右离开这一段小熊,可以证明这是最优的。

\(f(i)\) 表示考虑了前 \(i\) 只小熊的最小花费,显然有:

\[f(i)=\min_{j=1}^i \{f(i-j)+x_i-x_{i-j}+\min\{2(x_i-x_{i-j+1}), T\}\} \]

这个转移是 \(O(n^2)\),但是有极大的优化空间,将所有 \(j\) 按照 \(2(x_i-x_{i-j+1})\)\(T\) 的大小关系分成两部分,可以发现两部分分别可以用前缀最小值和线段树之类的进行优化。

[AGC006-C] Rabbit Exercise

\(\Rightarrow\)原题链接

首先考虑一次跳跃之后第 \(a\) 只兔子位置的变化,可以得到 \(x'_a=\frac{1}{2}(2x_{a+1}-x_a)+\frac{1}{2}(2x_{a-1}-x_a)=x_{a+1}+x_{a-1}-x_a\)。这个计算要进行 \(mk\) 次,很难优化。

考虑差分,设 \(d_i=x_i-x_{i-1}\) ,一次操作会改变 \(d_a\)\(d_{a+1}\) ,考虑其变化:

\[\begin{aligned} d'_a &= x'_a - x_{a-1}=x_{a+1}-x_a=d_{a+1}\\ d'_{a+1} &= x_{a+1}-x'_a =x_a-x_{a-1}=d_a \end{aligned} \]

可以发现这实际上是交换 \(d_a, d_{a+1}\)
因此可以处理出一轮操作之后每一个 \(d_a\) 去了哪里,这东西建图之后一定会形成若干个环,对于每一个环都计算出操作 \(k\) 轮之后的 \(d\) 就行了。

[ARC124-D] Yet Another Sorting Problem

\(\Rightarrow\)原题链接

依然是排列排序题,建图 \(i\rightarrow p_i\) ,可以得到若干个环。环内元素的交换实际上就是将环分裂成两个。环之间元素的交换是将两个环合并成一个。

对于跨越两个部分的环,也就是存在一个位置 \(\leq N\) ,存在一个位置 \(>N\) 的环,将其内部排好序的操作次数显然是环大小 \(-\ 1\)
对于只包含左边部分和只包含右边部分的两个环 \(c_1, c_2\),可以考虑将两个环合并。

因此答案为 \(n+m-c+2\max\{a,b\}\),其中 \(c\) 表示环的总个数(包括自环),\(a,b\) 分别表示只包含左边的环的个数和只包含右边的环的个数。

[ARC126-D] Pure Straight

\(\Rightarrow\)原题链接

看到 \(K\) 很小,可以考虑一下状态压缩 \(\verb|dp|\) 。在这之前先思考一下怎么拼凑出一个 \((1,2,\cdots K)\) 的子串。首先对于一个长度为 \(K\) 的排列,需要的步数显然是逆序对数,现在想想在一个排列中参杂一些不用来构成子串的元素,那么显然是要将他们全部跳过,可以是让所有在其右边的需要用的元素跳到其左边,也可以是在其左边的需要用的元素都移到右边。这些显然很适合用 \(\verb|dp|\) 来计算。

\(f(i,S,0/1)\) 表示当前考虑了前 \(i\) 个元素,已经拼凑出了一个 \(S\) 中的所有元素排好序的子串,这个子串的位置是否被固定,如果没有被固定,要求这个子串的末尾在 \(i\) 。考虑转移,显然对于一个新的元素,可以选择不使用,也可以选择加入 \(S\)

  • 如果不使用这个元素,那么如果子串位置被固定,所有在这个元素右边的,没有加入 \(S\) 的元素都必须向左跳过这个字符,而跳过这个元素需要 \(|\complement_U S|\) 步;如果没有被固定,那么这个子串需要跳过这个字符,这需要 \(|S|\) 步,接下来可以选择是否在这个位置固定子串。
  • 如果使用这个元素,假设其是 \(X\),如果子串位置不固定,这个字符首先要跳到子串中恰当的位置,这需要 \(\sum_{y\in S}[y>X]\) 步,相当于求个逆序对数;如果子串位置被固定了,但是先前已经计算了这个元素跳过无用元素所需要的操作数,所以既然是相同的步数。

[ARC125-D] Unique Subsequence

\(\Rightarrow\)原题链接

\(f(i)\) 表示结尾为第 \(i\) 个元素的独一无二子序列的个数,那么可以得到转移:

\[f(i)=\sum_{j<i}f(j)\times[\forall j<k<i,a_k\ne a_j, a_k\ne a_i] \]

这个显然可以用线段树或者一个桶优化。

[ARC130-D] Zigzag Tree

\(\Rightarrow\)原题链接

可以想到树形 \(\verb|dp|\) ,具体而言:

\(f(u,x), g(u,x)\) 分别表示子树 \(T_u\) 中,节点 \(u\) 的值为子树中第 \(x\) 小的,设定 \(u\) 的父亲要比 \(u\) 小/大的方案数。转移方式考虑树形背包式的合并子树。考虑将 \(g(v,?)\) 合并到 \(f(u,?)\) 中。显然这时候需要另 \(v\) 的值比 \(u\) 的值小,同时需要枚举 \(T_v\) 中多少个值比 \(u\) 的值要小,这时可以得到 \(O(n)\) 的刷表转移:

\[\mathrm{foreach}~~z\in [y,|T_v|]\cap \mathbb{Z}, f'(u,x+z)\leftarrow \binom{x+z-1}{x-1}\binom{|T_u|+|T_v|-x-z}{|T_u|-x}f(u,x)g(v,y) \]

这个可以直接使用前缀和优化,做到 \(O(1)\) 刷表转移。

同理,要将 \(f(v,?)\) 合并到 \(g(u,?)\) 中,可以使用下面的方式:

\[\mathrm{foreach}~~z\in [y,|T_v|]\cap \mathbb{Z}, f'(u,x+z-1)\leftarrow \binom{x+z-2}{x-1}\binom{|T_u|+|T_v|-x-z+1}{|T_u|-x}g(u,x)f(v,y) \]

posted @ 2021-11-03 20:27  juruohjr  阅读(35)  评论(0编辑  收藏  举报