ARC 做题笔记 - ARC155~ARC159
ARC155
A. ST and TS Palindrome
用回文串疯狂对偶过去再对偶回来,可以得到最后的回文串必然有长度为 \(2n\) 的周期,每个周期均为回文串。同时得到周期 \(T\) 为 \(S\) 的子串,\(T+r(T)\) 为 \(s\) 的周期。因此我们直接暴力枚举 \(T+r(T)\),判断是否合法即可。
Submission #49147521 - AtCoder Regular Contest 155
B. Abs Abs Function
考虑先拆绝对值。注意到拆掉第一层绝对值以后答案可以直接变为如下形式。
我们试图进一步去掉分类讨论。由于所有二元组均为正数,所以内层绝对值实际上让整体的绝对值变小,所以原式可以直接写成 \(||i-j_{first}|-j_{second}|=\min(|i-(j_{first}+j_{second})|,|i-(j_{first}-j_{second})|)\)
这样就能做了。我们直接把 \(j_{first}+j_{second},j_{first}-j_{second}\) 往 set 里扔。查询直接在 set 里 lower_bound 求前驱后继即可。
Submission #49148422 - AtCoder Regular Contest 155
C. Even Sum Triplet
更是魔怔。考虑如果一开始所有奇数两两不相邻,所有奇数就充当了断点的作用,我们可以做的只有把所有极长偶数连续段任意重排。否则我们可以直接把所有奇数移到左边,然后插进去偶数,把奇数任意重排,再把偶数移出来,然后对最后的偶数连续段排序。
而这个过程显然可逆,因此我们对 \(a\) 和 \(b\) 分别做如上变换后判断是否相等即可。
注意一个细节是偶数连续段长度至少为 \(3\) 才能重排。
Submission #49164905 - AtCoder Regular Contest 155
D. Avoid Coprime Game
这个题还挺简单的。
我们考虑做完第一次以后,会有一些质因子集合。现在我们所有的数被分为了不会影响集合和会导致集合缩小的两种。对于前者我们放到后面讨论。考虑只有后者的情况。此时是一个容易的的博弈论。对于一个位置 \(i\),枚举其所有因数 \(d\),判断是否存在 \(a_j\) 满足 \(\gcd(i,a_j)=d\),然后直接转移。判定性问题可以简单容斥解决。
接下来考虑那些不会导致集合大小缩小的数。注意成为不会让集合缩小的数的数不会再次成为会导致集合缩小的,所以操作这些数只会导致先后手改变。因此我们直接设 \(f(i,0/1)\) 表示当前 \(G=i\),当前先后手状态为 \(0/1\),是否存在必胜策略,转移类似转移即可。
Submission #49165438 - AtCoder Regular Contest 155
E. Split and Square
首先建出线性基。我们考虑一次操作会导致线性基怎样变化。假设基底为 \(e_1,e_2,\ldots,e_n\),考虑把包含 \(e_i\) 的数划分到集合 \(T_1\) 中,其余的划分到 \(T_2\) 中,则经过一次操作后,\(e_i\) 一定被消去,因此我们得到了一个次数为 \(\log_2 A\) 的做法。
考虑我们能否一次让线性基上多位变为 \(0\)。考虑一对 \((e_i,e_j)\) 被同时消去的条件,即 \(\forall x\in S,(e_i\in x)\oplus(e_j\in x)\)。其中 \(\oplus\) 表示逻辑异或。但经过一次操作后,集合 \(S\) 中必然存在 \(0\),即上条件必不能满足,所以如果让多位变为 \(0\) 只可能发生到第一位。
到这里已经可以做了,但是一个更高妙的方法是,对 \(a\) 全部异或一个数字 \(a_1\) 在 \(n>1\) 时显然不会影响答案大小,因此我们首先全体异或 \(a_1\),这样保证 \(S\) 中一定存在 \(0\),然后求线性基大小即可。注意特判 \(n=1\)。
Submission #49166366 - AtCoder Regular Contest 155
F. Directable as Desired
我草,真有水平。
先把原问题变成边带编号,树有根的问题。这里的编号是为每个点的出边赋编号。假设这个问题的答案是 \(B\),原问题为 \(A\),则有 \(B=n\prod\limits_{i=1}^n d_i!A\)。
考虑如何求解 \(B\)。我们把问题分为三步。
- 钦定一个点集 \(S\),其有一条指向根的出边。
- 确定这些出边的终点。
- 确定剩下的边。
先钦定一个点集 \(S\),那么钦定出边编号的方案数是 \(\prod\limits_{u\in S} d_u\)。然后考虑确定出边终点的方案数,注意到可以新建一个超级根把所有不在 \(S\) 中的点的父亲钦定为这个超级根,这相当于是限定 \(0\) 号点度数的 prufer 序计数。方案数为 \(\dbinom{n-1}{n-|S|-1}n^{|S|}\)。但是我们的集合 \(|S|\) 是钦定的,所以最后方案数除掉一个 \(\dbinom{n}{|S|}\) 得到 \(n^{|S|-1}(n-|S|)\)。
最后考虑确定剩下的边的方向。注意到剩下的边的连向和起点无关,且每次都会删掉终点,相当于将所有终点任意顺序排列,方案数为 \((n-|S|-1)!\)。把三部分乘起来就是对于一个集合 \(|S|\) 的答案。
注意到和 \(S\) 内容有关系的只有 \(\prod\limits_{u\in S}d_u\)。这部分是背包,我们容易使用分治 ntt 做到 \(O(n\log ^2 n)\) 求出对于固定 \(i\),\(\sum\limits_{|S|=i} \prod\limits_{u\in S} d_u\) 的值。因此枚举 \(|S|\) 统计答案即可。
Submission #49183824 - AtCoder Regular Contest 155
ARC156
A. Non-Adjacent Flip
细节题。首先判掉 \(1\) 的个数为奇数的情况。对于偶数,我们进行一些分类讨论。考虑贪心,我们把 \(1\) 排序以后,假设有 \(cnt\) 个 \(1\),我们可以考虑把第 \(i\) 个和第 \(i+\dfrac{cnt}{2}\) 个匹配消去,次数为 \(\dfrac{cnt}{2}\) 次。这个做法会出问题当且仅当 \(cnt=2\) 且这两个相邻。去掉 \(n=2\) 和 \(n=3\) 的无解情况。\(n=4\) 是比较特殊的,当二者相邻且位于位置 \(2\) 和 \(3\) 时需要三次,剩下 \(cnt=2\) 的情况均为两次。
Submission #38971674 - AtCoder Regular Contest 156
B. Mex on Blackboard
考虑我们每次能插进去的数实际上是 \([0,\mathrm{mex}(A)]\) 中的任意一个。因此不难想到把操作分为增加 \(\mathrm {mex}(A)\) 和放进去重复的数两部分。考虑枚举 \(\mathrm{mex}(A)\),这样第一部分的操作次数固定,设为 \(x\)。第二部分相当于把 \(k-x\) 个球放进 \(\mathrm{mex}(A)+1\) 个盒子,可以为空的方案数,这部分是简单插板,所以做完了。
Submission #38976640 - AtCoder Regular Contest 156
C. Tree and LCS
答案下界显然为 \(1\),考虑如何得到这个下界。
初始构造排列 \(p_i=i\)。我们维护一个叶子集合,每次选两个叶子,交换两者排列权值,然后删掉这两个叶子,再把新叶子加入集合,直到不存在两个以上的叶子。
考虑这个做法为什么是对的。对于一个点 \(u\),如果其出现在最长公共子序列中,则必然包含 \((u,v)\) 这条路径,如果要在 \(p_u\) 后面接值,接上的东西一定是 \(u\) 子树内一点 \(x\) 的 \(p_x\),但这种构造保证了 \(p_x\) 若出现一定不出现在 \(u\) 的子树内(否则路径不为简单路径),而 \(x\) 在 \(u\) 的子树内,所以一定接不下去,因此答案为 \(1\)。
Submission #48249553 - AtCoder Regular Contest 156
D. Xor Sum 5
注意到,我们把 \(p\) 看成可重集划分等价类,此时我们只需要计算大小为奇数的等价类对答案的贡献即可。
考虑等价类大小怎么计算。考虑 Kummer 定理的扩展。容易证明多重组合数 \(\dbinom{K}{c_1,c_2,\ldots,c_n}\) 为奇数当且仅当 \(c_i\) 在二进制下构成了对 \(k\) 的划分。因此可以考虑直接数位 dp。naive 的想法是设 \(f(i)\) 表示划分到 \(K\) 的第 \(i\) 位,当前所有方案的异或和。然后再记一个 \(g(i)\) 表示方案数。但是这个没法转移,问题出现在进位上,把这个塞进状态里。设 \(f(i)\) 表示划分到 \(K\) 的第 \(i\) 位,当前所有方案在这一位的进位次数为 \(j\) 的方案数。同理记录 \(g(i,j)\)。转移是容易的。
唯一的问题是 \(j\) 那一维的大小,复杂度的证明可以类比下面的 ARC160C,这里不赘述了。
Submission #48251071 - AtCoder Regular Contest 156
E. Non-Adjacent Matching
更是厉害。
我们先瞪出来一个充要条件。如果没有不相邻的限制,充要条件是 \(K\) 为偶数且不存在点 \(u\) 度数超过 \(\dfrac{S}{2}\)。因为这个点所有向外连的边需要一个点花费 \(1\) 的度数吸收掉。否则我们容易通过每次在度数最大和第二大的点间连边构造出一个合法解。
接下来考虑不允许相邻存在边的限制,不幸的是我们此时的策略全部失效。
仿照上面的结论,我们猜测,充要条件为不存在相邻两个点度数和超过 \(\dfrac{S}{2}\)。
必要性不难证明。充分性考虑引入新变量 \(B_i=\dfrac{S}{2}-d_i-d_{i+1}\),考虑删掉一条边对 \(B\) 数组的影响。那么应该是全局减 \(1\),剩下的 \(u,u+1,v,v+1\) 四个位置加 \(1\)。如果 \(\min(B)\ge 1\),则这个操作显然可以进行,否则我们直接多次操作 \(i,i+2\) 和 \(i+1,i+3\),如果仍不能推成 \(0\),我们一定可以将 \(i\) 和 \(i+1\) 在途中和其它位置做配对,所以是正确的。
但这个条件有点难受。我们考虑容斥掉这个条件。注意到这种情况最多发生两次,且若为两次则必定相邻。所以我们直接对三种情况分类讨论。
- 无限制。
构造 \(F(x)=\sum\limits_{i=0}^m x^i=\dfrac{1-x^{m+1}}{1-x}\),所求即 \([x^k]\dfrac{F(x)^n}{1-x^2}\)。化式子为 \(G(x)=\dfrac{(1-x)^{m+1}}{1-x^2}\) 直接对上面二项式定理展开,然后再求 \(H(x)=G(x)(1-x)^{-n}\),再套二项式定理即可。
- 限制一个位置。
不妨先扔到前面,枚举前两个数的和 \(s\) 还有度数和 \(S\),后面相当于是 \([x^{S-s}]\dfrac{F(x)^{n-2}}{1-x^2}\),前面的方案数容易算出,后面的东西套上面的做法先算出各项系数,查询时 \(O(1)\) 计算即可。
- 限制两个位置。
后面的做法相同。考虑前面的方案。仍然枚举总和 \(S\) 和前三个数的和 \(s\)。我们考虑第二个数的取值 \(v\)。设 \(l=\max(0,\dfrac{S}{2}-x-1)\),如果 \(l>m\) 无解,否则为 \(x^v\sum\limits_{i=l}^m x^i\)。仍然套上面的做法,等比数列求和后分别记下分子分母即可。
因此总复杂度 \(O(m^2)\)。
Submission #49017025 - AtCoder Regular Contest 156
F. Make Same Set
我们先考虑这样一个弱化问题,第一种操作中,我们每次可以选 \(a_i\),选 \(b_i\) 或不选,第二种操作中我们可以选 \(a_i\),选 \(c_i\) 或不选。问最大集合大小。用这种方式生成的集合大小和原问题能生成的显然相等。这个问题的答案显然是上界,下界可以考虑钦定一个位置不做操作,对那个位置对位的另一个操作做讨论得到在这个位置两种操作全选 \(a_i\) 不劣。
对于这个问题,我们有网络流做法。考虑建三排点,第一排第三排均有 \(n\) 个点,分别代表每个位置的操作,源向第一排连边,第三排向汇连边。第二排代表每一个数。第一排中的每个点 \(i\) 向第二排中的 \(a_i,b_i\) 连边,第二排中的 \(a_i,c_i\) 向第三排中的 \(i\) 连边。为了限制每个数在集合里只出现一次,我们要把第二排再拆一次点,中间连边限制流量为 \(1\)。对这个图跑最大流即可得到上面问题的答案。
但是有一个很糟糕的问题是,在构造方案上,这个做法和原问题有差别。原问题没有不选操作,这意味着在原问题的方案中,第一排点的出边和第三排点的入边所代表的数中,至少应有一个存在于构造出的集合。而我们的网络流得到的方案不能保证这一点。我们考虑怎么修复这个问题。
我们称在第一排和第三排的点中,对应操作的两个数均不在构造的集合中的点为不合法点,反之为合法点。有一个惊人的结论是,我们注意到,在最大流单次增广的过程中,如果每次增广长度最短的路径,一定不会让一个本来合法的点变为不合法。证明是容易的,我们考虑什么样的增广路会导致合法点变成不合法。记 \(A_i,B_i,B'_i,C_i\) 为四排点中的第 \(i\) 个,\(S\) 为源,\(T\) 为汇。那么一条路径一定是经过了一条 \(B_i'\rightarrow B_i\) 的边。即路径形如 \(S\rightsquigarrow B'_i\rightarrow B_i\rightarrow A_j\rightarrow B_k\rightsquigarrow T\)。但根据不合法点的定义,\(S\rightarrow A_j\) 这条边的当前流量为 \(0\),所以 \(S\rightarrow A_j\rightarrow B_k\rightsquigarrow T\) 这条路径是一个更短的合法增广路。
因此我们如果有一个初始状态不存在不合法点,我们对这个初始方案做最大流增广后得到残量网络就是一个不存在不合法点的残量网络。对着这个残量网络构造方案即可。最后的问题是初始状态的选择。不难发现,我们只需要初始让每个操作均选 \(a_i\) 即可(即手动增广所有形如 \(S\rightarrow A_i\rightarrow B_{a_i}\rightarrow B'_{a_i}\rightarrow C_j\rightarrow T\) 的路径)。
代码使用了 atcoder/maxflow
,其增广方式为每次增广最短路径。
Submission #49020506 - AtCoder Regular Contest 156
ARC157
A. XXYYX
观察一些性质。注意到 \(\texttt{XY}\) 和 \(\texttt{YX}\) 会产生当且仅当 \(\texttt{X}\) 和 \(\texttt{Y}\) 的连续段交错,因此 \(|b-c|=1\)。然后特判掉 \(a\neq 0,b=0,c=0,d\neq 0\) 的情况,这意味着 \(\texttt{X}\) 和 \(\texttt{Y}\) 不能衔接。
容易证明一定可以构造出方案。具体而言,先在前面用 \(\texttt{XYXYXY}\) 的结构满足 \(b,c\) 的数量,然后在 \(\texttt{Y}\) 后插入适量的 \(\texttt{Y}\),\(\texttt{X}\) 后插入适量的 \(\texttt{X}\) 即可。
Submission #39180124 - AtCoder Regular Contest 157
B. XYYYX
考虑什么策略是比较优的。首先特判掉全串均为 \(\texttt{X}\) 的情况。注意到如果我们将一个 \(\texttt{Y}\) 填到两个相邻的 \(\texttt{Y}\) 中间答案会增加 \(2\),填到 \(\texttt{Y}\) 旁边会增加 \(1\),否则不改变。因此根据贪心我们要先尽量合并相邻连续段,然后再向连续段两侧填,直到填满。第一个过程可以使用堆维护,依据连续段长度排序后贪心选即可,第二次要填到连续段两侧,可以考虑队列维护,出队时向左右增广。
场上实现和上述做法略有不同,所以细节颇多。
Submission #39195896 - AtCoder Regular Contest 157
C. YY Square
比较典的题。看到和的平方首先考虑拆开维护方案数,和与平方的和,直接 dp 转移即可。
如果记录三种状态为 \(h,g,f\),则转移如下。
其中 \(a=[s(i-1,j)=s(i,j)=\texttt{Y}],b=[s(i,j-1)=s(i,j)=\texttt{Y}]\)。
Submission #39191350 - AtCoder Regular Contest 157
D. YY Garden
注意到每个块要求恰好有两个 \(\texttt{Y}\),不妨考虑从这一点入手。
首先记录 \(\texttt{Y}\) 的个数为 \(x\),那么要求 \(x\) 为二的倍数。又因为设置 \(h-1\) 个横向栅栏,\(w-1\) 个纵向栅栏后,总的块数为 \(hw\),所以 \(h\) 和 \(w\) 必定为 \(x\) 的因数。
首先判掉 \(x\) 为奇数的情况。我们枚举 \(h\),则 \(w\) 固定且为 \(\dfrac{x}{2h}\)。考虑对于一个这种状态我们如何计算方案。再次观察,由于 \(h\) 和 \(w\) 固定,则若我们只观察横向划分,每一块里恰好要有 \(2w\) 个 \(\texttt{Y}\)。纵向划分同理。下面只讨论横向的情况。注意到此时一个栅栏的位置会被固定在一个全部由 \(\texttt{X}\) 构成的行,否则均会导致这一块中的 \(1\) 的个数不为 \(2w\)。注意到每一个栅栏被固定的范围不交,因此如果确定了 \(h\) 和 \(w\) 以后,方案数的计算可以直接通过乘法原理将每个栅栏可能存在的位置个数相乘得到方案数。然后模拟任意一种划分,二维前缀和判断是否合法。最后将所有合法的 \(h\) 取值所导出的方案数相加即可。
时间复杂度 \(O(HWd(HW))\),其中 \(d\) 为约数个数函数。常数不大,因此可以通过。
Submission #48193657 - AtCoder Regular Contest 157
E. XXYX Binary Tree
第一个观察是没有 \(\texttt{YY}\) 的这个要求告诉我们如果我们把填 \(\texttt{Y}\) 的点看成白色,那么所有白点构成了一个独立集。但是只有这一点做不了,所以我们考虑其它限制带来的信息。
观察 \(\texttt{YX}\)。由于原树是一个满二叉树,而 \(\texttt{Y}\) 又构成独立集,所以每个填 \(\texttt{Y}\) 的节点都会贡献零个或两个 \(\texttt{YX}\)。因此 \(\texttt{YX}\) 的个数一定是偶数个。这也启示我们一件事,如果填在叶子上的 \(\texttt{Y}\) 的个数固定了,\(\texttt{Y}\) 的总个数也随之确定,即在非叶子上的 \(\texttt{Y}\) 为定值。
再考虑 \(\texttt{XY}\) 的个数带给我们的限制。我们惊讶的发现,由于 \(\texttt{Y}\) 是独立集,所以每一个不在根节点上的 \(\texttt{Y}\) 会恰好贡献一个 \(\texttt{XY}\) 结构,也就是说不在根节点上的 \(\texttt{Y}\) 的个数为定值。结合上文所述,如果我们固定了根节点填什么,我们就可以直接知道我们要在叶子上填多少个 \(\texttt{Y}\),在非叶子上填多少个 \(\texttt{Y}\)。由于 \(A+B+C=n-1\),此时 \(\texttt{XX}\) 的限制一定天然满足。
此时正解已经呼之欲出了。考虑一个 dp,设 \(f(i,j,0/1)\) 表示考虑到位置 \(i\),已经在 \(j\) 个叶子上填了 \(\texttt{Y}\),当前节点是否填 \(\texttt{Y}\) 能填的最多的 \(\texttt{Y}\) 的个数。转移是容易的,即 \(f(u,i+j,0)\leftarrow \max(f(v,i,0),f(v,i,1))+\max(f(w,j,0),f(w,j,1)),f(u,i+j,1)\leftarrow f(v,i,0)+f(w,j,0)\)。然后我们分根节点是否填 \(\texttt{Y}\) 讨论,方案合法当且仅当对应的根节点上的 dp 值不小于需要填的 \(\texttt{Y}\) 的数量。具体数量参数可以参考代码。
复杂度分析同树形背包。
Submission #48212117 - AtCoder Regular Contest 157
F. XY Ladder LCS
很漂亮的一道题目,我一点不会。
我们首先考虑一些暴力。我们从前向后扫描每一个位置,设 \(f(i,S)\) 表示考虑到位置 \(i\),从上次匹配位置到当前位置的状态是 \(S\),所能达到的最长公共子序列的最小字典序。转移时,分当前位置的字符是否选中参与到子序列中讨论。若选中,注意到一个很好的性质是无论我们匹配一个 \(\texttt{X}\) 还是 \(\texttt{Y}\),我们一定会选择 \(S\) 当中最靠左的一个,因此我们的转移可以 \(O(1)\) 进行。具体而言,我们对每个 \(S\) 所代表的状态预处理出其第一个 \(\texttt{X}\) 所在的位置和 \(\texttt{Y}\) 所在的位置,转移时舍弃匹配位置以前的部分,将其加入答案,然后把剩余的那个字符拼到当前备选状态的末尾,转移到这个状态对应的位置,否则直接拼到备选状态,分到底把哪个拼上去讨论即可。时间复杂度 \(O(n2^n)\)。
接下来有一个惊为天人的结论,答案的下界是 \(\lfloor \dfrac{2n}{3}\rfloor\)。原因是,如果我们把每三个相邻字符分到一组,这一组里的能贡献出的 LCS 长度至少为 \(2\)。可以使用一些分讨或直接暴搜证明,这里不再赘述。因此我们两个匹配的位置距离至多为 \(\lceil \dfrac{n}{3} \rceil\)。所以暴力 dp 第二维的状态为 \(2^{\frac{n}{3}}\),总时间复杂度为 \(O(n2^{\frac{n}{3}})\),可以通过此题。
代码实现上,我们需要把字符串映射为数字,官解给了一种很巧妙的方式是把长度为 \(n\) 的字符串看做一个长度为 \(n+1\) 的二进制数,后 \(n\) 位表示把 \(\texttt{X}\) 看成 \(1\),\(\texttt{Y}\) 看成 \(0\) 后对应的二进制数,第一位代表终止符,始终为 \(1\),这样映射后取最大值恰好对应了题目中要求的操作,容易 dp 解决。
Submission #48213283 - AtCoder Regular Contest 157
ARC158
A. +3 +5 +7
首先我们直接把三种操作看成 \(-2,0,+2\),很容易观察到操作不改变奇偶性,因此我们得到了第一个必要条件。同时注意到这三个操作不改变所有数的加和,所以结果一定是平均数,所以也要求平均数是整数。容易证明,在满足上述条件的情况下,我们可以通过每次选取最大值和最小值分别做 \(+2\) 和 \(-2\) 操作构造一组合法解,且这组解一定是最小解,所以做完了。
Submission #48230265 - AtCoder Regular Contest 158
B. Sum-Product Ratio
首先对原式子进行拆分,即拆成 \(\dfrac{1}{x_k}(\dfrac{1}{x_i}+\dfrac{1}{x_j})+\dfrac{1}{x_ix_j}\),注意到 \(x_i,x_j\) 固定的时候,若存在 \(x_k\) 的三种取值 \(a,b,c\) 满足 \(a<b<c\),则无论以最大化还是最小化为目的, \(b\) 均不会成为较优解。根据这个引理,我们可以把 \(x_i,x_j,x_k\) 调整为正负的绝对值最大最小的十二个数。因此我们只需要把这十二个数拉出来暴力枚举算出最大值和最小值即可。
Submission #48230863 - AtCoder Regular Contest 158
C. All Pair Digit Sums
很典的一道题。注意到 \(f(a+b)=f(a)+f(b)-9c\),其中 \(c\) 代表十进制下加法的进位次数。前面的 \(f(a)\) 和 \(f(b)\) 在所有数对里的贡献是容易维护的。所以我们维护一个数和其它数相加的进位总次数即可。再把发生在每一位上的进位拆开考虑,\(a+b\) 在位置 \(k\) 上发生进位的充要条件是 \(a\bmod 10^k+b\bmod 10^k\ge 10^k\),所以对于每一个数位 \(k\),我们保留每个数模 \(10^k\) 后的结果后排序双指针即可计算出总的进位次数。时间复杂度 \(O(n\log V)\),其中 \(V=\max\limits_{i=1}^n A_i\)。
Submission #48233406 - AtCoder Regular Contest 158
D. Equation
最有脑子的一集。
注意到等式两侧次数相差恰好 \(1\) 且均为齐次式。记录左式为 \(F(x,y,z)\),右为 \(G(x,y,z)\),则如果我们能够构造出一组 \(x,y,z\) 满足 \(F(x,y,z)=kG(x,y,z)\),则 \(F(\dfrac{x}{k},\dfrac{y}{k},\dfrac{z}{k})=G(\dfrac{x}{k},\dfrac{y}{k},\dfrac{z}{k})\)。因此随机构造即可。唯一的问题是 \(k\) 不存在实数域的取值或取 \(0\),即 \(F(x,y,z)=0\) 或 \(G(x,y,z)=0\) 的这种情况。但是官方题解经过一些分讨证明了出现这种情况的概率不大于 \(\dfrac{1}{4}\),所以复杂度有保证。由于我没看懂证明,所以这里不写了,感兴趣可以自行研究官方题解。
Submission #42839334 - AtCoder Regular Contest 158
E. All Pair Shortest Paths
我草我咋不会这个题。
注意到从一个格子走到另一个横坐标单调变化,因为一但回头就会把拐弯处的两个格子填满导致回不去。也就是说,对于横坐标分别为 \(L\) 和 \(R\) 的两个格子,其最短路必定经过且仅经过横坐标在 \([L,R]\) 中的格子。因此我们有了暴力,枚举两个格子,设 \(f(i,0/1)\) 表示考虑到位置 \(i\),当前在上方还是下方格子的最短路,转移是容易的。
对于这种问题,一个很自然的解决技巧是分治,假设当前分治中心是 \(mid\),我们现在要计算所有跨过 \(mid\) 的格子所带来的贡献。根据上述结论,我们容易发现每条这种路径一定会经过 \(mid\),因此不妨考虑在 \(mid\) 处将路径拼接起来。记 \(disL(i,0/1,0/1)\) 表示从格子 \(i\) 的上半或下半部分,走到 \(mid\) 的上半或下半部分的最短路,要求 \(i\) 在 \(mid\) 的左侧。同理设 \(disR(i,0/1,0/1)\)。考虑一对格子 \((i,j)\),不妨令 \(i\) 在 \(mid\) 的左边,其对答案的贡献是 \(\min(disL(i,0)+disR(j,0),disL(i,1)+disR(j,1))\)。
考虑拆开最小值讨论,取前者当且仅当 \(disL(i,0)+disR(j,0)<disL(i,1)+disR(j,1)\),移项有 \(disL(i,0)-disL(i,1)<disR(j,1)-disR(j,0)\)。两侧对 \(i,j\) 独立。因此按照 \(disL(i,0)-disL(i,1)\) 的顺序降序排左部点,\(disR(i,0)-disR(i,1)\) 的顺序升序排右部点,枚举左部点,用前缀和配合双指针即可简单算出该点和所有右部点对答案的贡献。
时间复杂度 \(O(n\log^2 n)\),瓶颈是排序。
Submission #48241737 - AtCoder Regular Contest 158
F. Random Radix Sort
第一个观察是,如果存在一种合法方案,我们可以确定每一个 \(B_i\) 究竟由哪个 \(A_i\) 转移过来。原因是排序是稳定排序,所以对于相同的数字,其相对顺序不会改变。我们记 \(B_i\) 由 \(A_{pos_i}\) 转移而来。
继续观察性质,注意到如果我们记录操作序列的选择为 \(p_1,p_2,\ldots,p_m\),则整个操作可以描述为按照 \(p_m\) 为第一关键字,\(p_{m-1}\) 为第二关键字,以此类推进行排序。因而我们发现对于每种操作只有最后一种有用。
接下来考虑 \(B\) 序列对操作序列的限制。我们注意到如果 \(B_i\neq B_{i+1}\),将所有不等的位划分为 \(S,T\) 两个集合,\(S\) 表示 \(B_i\) 的这一位大于 \(B_{i+1}\) 的,\(T\) 相反。那么这个位置相当于限制如果填了 \(T\) 中的一个数字,则后面必须填一个 \(S\) 中的。且如果原序列中顺序不一样也要至少排一次 \(S\) 中的。我们定义这种限制关系为 \(lim(x,S)\),表示在填 \(x\) 之前 \(S\) 集合必须被填上一个数字。
然后可以开始状压。令 \(f(S)\) 表示在只考虑最后一次出现的情况下,填完了 \(S\) 中的数的方案数。从后向前考察序列,转移的时候枚举一个数字 \(x\),检查是否存在一个限制 \(lim(x,T)\) 使得 \(T\cap S=\varnothing\)。因此对每一个 \(x\),对 \(lim(x,T)\) 做高维前缀和,然后检查是否有 \(lim(x,\complement_U S)\) 即可。
结束了吗?还没有。我们还需要计算对于一个集合 \(S\) 剩下空位的填法。相当于是让我们把 \(m\) 个位置划分为无序的若干组,每组填上同一个数。这显然是第二类斯特林数,因此方案为 \(\begin{Bmatrix}m\\\mathrm{popcount}(S)\end{Bmatrix}\)。所以处理第二类斯特林数后做 dp 即可。时间复杂度 \(O(n\log n+nk+k2^k)\),原因是高位前缀和那里可以状压省掉一个 \(k\)。
Submission #48248921 - AtCoder Regular Contest 158
ARC159
A. Copy and Paste Graph
不妨猜结论,从 \(u\) 到 \(v\) 的最短路相当于从 \((u-1)\bmod n+1\) 到 \((v-1)\bmod n+1\) 的最短路。
证明考虑反证。假设最短路不是 \((u-1)\bmod n+1\) 到 \((v-1)\bmod n+1\) 的最短路,那么我们将路径上所有的点 \(x\) 映射为 \((x-1)\bmod n+1\),则得到一条从 \((u-1)\bmod n+1\) 到 \((v-1)\bmod n+1\) 更短的路径,和假设不符,所以原命题成立。
Submission #48268533 - AtCoder Regular Contest 159
B. GCD Subtraction
注意到将 \(x,y\) 同时变为 \(x-\gcd(x,y),y-\gcd(x,y)\) 不会使得 \(\gcd(x',y')\) 变小,更确切的说,\(\gcd(x,y)\mid \gcd(x',y')\)。这意味着本质不同的 \(\gcd(x,y)\) 个数只有 \(O(\log V)\) 个,意味着如果我们能快速找到减多少次能够使得 \(\gcd(x,y)\) 变化,复杂度是可接受的。而这个事情也是容易做到的。不妨每次先令 \(x'=\dfrac{x}{\gcd(x,y)},y'=\dfrac{y}{\gcd(x,y)}\),显然这不影响减法次数。注意到如果 \(\gcd(x,y)\) 变化,它增加的倍数至少应该同时是 \(a\) 和 \(b\) 的因数。所以我们直接枚举 \(a-b\) 的因数,然后计算次数后返回所有因数为达到目标所做的减法次数的最小值即可。
Submission #48268912 - AtCoder Regular Contest 159
C. Permutation Addition
首先试图发掘充要条件。考虑 \(n\) 为奇数的情况,每次加法不会改变 \(\sum\limits_{i=1}^n a_i\bmod n\) 的值,因此如果让所有数相等,要求 \(\sum\limits_{i=1}^n a_i\equiv 0\pmod n\)。注意到我们可以通过钦定一个排列 \(p=\underbrace{\overbrace{p_1,p_2,\ldots,1}^i,p_{i+1},\ldots,2}_j\ldots p_n\),然后再依据 \(p\) 钦定一个排列 \(q=\underbrace{\overbrace{n-p_1+1,n-p_2+2,\ldots,n-1}^i,n-p_{i+1}+1,\ldots,n}_j\ldots n-p_n+1\)。注意到我们对原序列操作 \(p\) 和 \(q\) 即可使得 \(i\) 位置相对减一,\(j\) 位置相对加一的效果。依此每次操作最小值和最大值直到最小值和最大值相等即可得出合法方案。
接下来可以考虑 \(n\) 为偶数。我们现在只能确定其不会改变 \(\sum\limits_{i=1}^n a_i\bmod \dfrac{n}{2}\) 的值,那么首先要求 \(\sum\limits_{i=1}^n a_i\equiv 0\lor \sum\limits_{i=1}^n a_i\equiv \dfrac{n}{2}\pmod {n}\),分类讨论一下,如果 \(\sum\limits_{i=1}^n a_i\equiv 0\pmod {\dfrac{n}{2}}\),则直接按照奇数做,否则随机操作一次改变奇偶性即可。
Submission #48269603 - AtCoder Regular Contest 159
D. LIS 2
怎么 ARC 的 D 这么唐。
考虑 \(f(i)\) 表示强制选到位置 \(i\) 的右端点的最长上升子序列数。考虑转移,\(f(i)=\max(\max\limits_{r_j<l_i} f(j)-l_i,\max\limits_{r_j\ge l_i} f(j)-r_j)+r_i\)。分别建立以值域为下标,支持单点修改,维护 \(f(j)\) 和 \(f(j)-r_j\) 的区间最值的线段树即可。
Submission #48273091 - AtCoder Regular Contest 159
E. Difference Sum Query
牛逼题。
注意到题目中的操作实际上就是加权二分的次数。考虑建出来二叉搜索树,每一层的根节点为当前确定区间为 \([l,r]\) 后计算出的 \(mid\)。然后儿子为 \([l,mid-1]\) 和 \([mid+1,r]\)。那么深度即为该点的值。由于二叉搜索树的中序遍历为 \(1,2,\ldots,n\),所以 \(x_i\) 和 \(x_{i+1}\) 在二叉搜索树上必有祖先后代关系,所以 \(|x_i-x_{i+1}|\) 相当于是这两个点在二叉搜索树上的距离。而题目中 \(\max(\dfrac{a_i}{b_i},\dfrac{b_i}{a_i})\leq 2\) 的限制保证了二分次数不超过 \(O(\log n)\) 次,因此我们可以直接暴力计算这些点集的距离和。具体而言,我们直接在二叉搜索树上递归区间,如果询问区间 \([ql,qr]\) 完全包含当前区间 \([l,r]\),答案为 \(2(r-l+1)\),否则向两侧递归,并将答案加二。最后减去 \(dep_l\) 和 \(dep_r\) 带来的额外贡献即可。
复杂度 \(O(q\log n)\)。
Submission #48326930 - AtCoder Regular Contest 159
F. Good Division
考虑满足题意的区间长啥样。首先不存在绝对众数,然后长度为偶数。
原因是有绝对众数一定删不干净,否则每次任意找到当前出现次数最多的数和旁边一个不相同的位置,删掉两者继续做,由于这个数不是绝对众数,因此每次一定有这样的位置。
因此有了 \(O(n^2)\) 的暴力,\(f(i)\) 表示到位置 \(i\) 的方案数,然后从 \(i\) 向前,维护绝对众数转移即可。
然后考虑 CDQ 分治维护 dp。注意到绝对众数有很好的性质,即如果 \(x\) 在 \([l,r]\) 中为绝对众数,则其在 \([l,mid],[mid+1,r]\) 中的至少一个为绝对众数。因此我们向左算出 dp 值,考虑向右计算答案。注意到左侧的绝对众数改变次数为 \(O(\log n)\) 级别,因为每多一个改变需要的数字个数翻倍。先做一步容斥,变成减去左侧的若干 dp 值。维护出左侧的 \(O(\log n)\) 个绝对众数,枚举每一个众数,记为 \(x\),做 dp 值的后缀和,然后顺序扫描右侧,每次判断是否以 \(x\) 为绝对众数,若不存在跳过,否则减去使得该区间绝对众数恰为 \(x\) 对应位置的后缀和即可。
精细实现复杂度可以做到 \(O(n\log^2 n)\)。