QOJ 板刷记录4

2025.8.29


#36 绝望

题意简述

定义合法序列要求前缀异或和严格递增,现在给你数组 \(a\),请构造一个最长合法序列 \(b\),要求 \(b\) 中的数都在 \(a\) 中出现过,输出 \(b\) 的长度。

绝望了,根本不会做。

题解

妙妙 \(\text{dp}\) 题啊,喜欢这道题。假设说当前的前缀异或和是 \(x\),我们要将 \(a_i\) 加入到 \(b\) 序列,如果要是前缀异或和变大一定要满足在二进制下,\(a_i\) 的最高位对应的位在 \(b\) 中为 \(0\)。原因显然,因为比较两个数大小看的是最靠左的不同位,根据异或的性质,\(a_i\) 的最高位 \(1\) 对应的位一定是异或后最靠左的不同位,想要让异或后变大,异或前必须为 \(0\)。显然如果一个位没有任何 \(a\) 的最高位等于这个位,这个位对答案一定毫无影响,我们把这些位删掉,包括以后的叙述都是在删掉对答案无影响的位的基础上叙述的。

我们接下来考虑一个性质, 如果我们在 \(x\) 之后要取 \(a_i\),如果想要让答案取到最优那么 \(a_i\) 除了最高位其他所有位如果是 \(1\),那么 \(b\) 对应的这个位一定也是 \(1\)。否则假如 \(b\) 对应的这位是 \(0\),我们肯定可以用另一个最高位是这位的数(显然肯定存在,毕竟如果没有的话这位已经被删了),这个数肯定比 \(a_i\) 更优,能使得答案更多,原因显然感性理解一下即可。所以对于任意一个数 \(a_i\) 我们加到 \(b\) 后头我们就可以理解为 把 \(a\) 最高位对应的 \(b\) 的位的 \(0\) 变成 \(1\),剩余 \(a\) 中是 \(1\) 的为变成 \(0\)

那我们就可以列出 \(\text{dp}\) 方程,设 \(dp[k]\) 表示让 \(k\) 的二进制位从 \(0\) 变为 \(1\) 最多可以放多少个数,\(high(a_i)\) 表示 \(a_i\) 这个数的最高位,显然有转移:

\[dp[k]= 1+max_{i=1}^n\sum_{j<k且a_i在第j位是1} dp[j] \]

最后我们要求的答案就是 \(\sum dp[k]\) 了。

然后写一下就好了,时间复杂度为 \(O(n\log^2 V)\)


#37 蜀道易

题意简述

不会简述题意,我选择搬运原题。

定义一棵双根树为有两个特殊结点,即根结点 \(S\) 与反根结点 \(T\) 的树。两棵双根树 \(A\)\(B\) 的乘积 \(A*B\) 定义如下:

  • 树A*B中共有 \(n_An_B\) 个结点(\(nA\)\(nB\) 分别表示两棵树的结点数),以点对 \((i,j)\) 表示,其中 \(1\le i\le nA\)\(1\le j\le nB\)

  • 对于所有 \(1\le u\le nA\)\(1\le v,w\le nB\),若 \(v,w\)\(B\) 中相邻,则 \((u,v),(u,w)\)\(A*B\) 中相邻。

  • 对于所有 \(1\le u,v\le nA\),若 \(A\)\(u\)\(v\) 的父亲(即 \(u\)\(v\)相邻,且前者距离 \(S_A\) 更近), 则 \((u,TB),(v,SB)\)\(A * B\) 中相邻。

  • \(A * B\)的根结点为 \((S_A,S_B)\),反根结点为 \((T_A,T_B)\)。 下面是一个例子:

现在给出一棵双根树,问他和自己乘 \(k\) 次得到的树中点对的距离和。

题解

根据经典 \(\text{trick}\)

\[\sum_{u,v=1}^{n}dis(u,v)=\sum_{u=1}^nsz[u]\times (n-sz[u])=n\times\sum_{u=1}^nsz[u]-\sum_{u=1}^nsz[u]^2 \]

其中 \(sz[u]\)\(u\) 节点的子树大小,\(n\) 是节点数。

节点数显然就是 \(n^k\),那么我们只需要求出 \(\sum_usz[u]\) 以及 \(\sum_usz[u]^2\) 就做完了。

对于 \(A*B\) 的过程,我们发现只有是 \(B\) 的假根的祖先的 \(sz\) 会受到影响,否则不会变。

我们设 \(n_A\) 代表 \(A\) 的节点数,\(sz_A(u)\) 表示 在 \(A\)\(u\) 子树的大小,\(Pa_A(u)\) 代表 \(u\)\(T_A\) 的祖先(是就是 \(1\),否则是 \(0\)),\(f_A\) 代表 \(A\)\(sz\) 和,\(g_A\) 代表 \(A\)\(sz^2\) 和,\(k_A\) 表示 \(A\)\(T_A\) 祖先个数,\(h_A\) 表示 \(A\)\(T_A\) 祖先 的 \(sz\) 和。

则有:

\[n_{A*B}=n_A\times n_B\\\\ sz_{A*B}(u,v) = (sz_A(u) - 1) \cdot n_B \cdot \text{Pa}_B(v) + sz_B(v)\\\\ f_{A*B}=\sum_{u,v}sz_{A*B}(u,v)\\ =\sum_{u,v}(((sz_A(u)-1))n_BPa_B(v)+sz_B(u))\\ = n_B k_B (f_A - n_A) + f_B \cdot n_A\\\\ g_{A*B}=\sum_{u,v}(sz_{A*B}(u,v))^2\\ =\sum_{u,v}(((sz_A(u)-1))n_BPa_B(v)+sz_B(u))^2\\ =\sum_{u,v}((sz_A(u)-1))n_BPa_B(v))^2+2\sum_{u,v}(sz_A(u)-1))n_BPa_B(v)sz_B(u)+\sum_{u,v}sz_B(u)^2\\ =k_B n_B^2 (g_A - 2f_A + n_A) + 2n_B h_B (f_A - n_A) + g_B \cdot n_A \]

我们发现每次自乘和 \(B\) 有关的都是常量,所以我们可以写出转移矩阵,做矩阵快速幂就能直接求出答案了。


#39 Love Polygon

题意简述

给你一个每个点出度都是 \(1\) 的有向图,现在可以花费 \(1\) 的代价使一个点的出边改变指向另一个边,求最小化花费使图变成若干个不相交的二元环并且每个点都在一个二元环之中。

题解

贪心,我们发现我们要尽量保留原图中的边,如果在原图上就是二元环那么我们显然没必要拆开,所以直接把这种点从原图中删除,如果有点连到这个二元环上了,我们直接增加代价让这个点变成可以连向任意点的点。图中剩下的部分就一定是没有二元环的了,我们要尽量让原图的边还保留,我们发现如果有多个点指向它时,我们选择其中一个点,然后就保留了一条边,但是这样我们不知道选择哪个,但是如果一个点没有点指,我们为了保留尽量多的边,我们只能让它指的点指向它,然后这两个点删除,仍然是把连向这个点的点变成指向任意点的点,并且增加对应的代价。这样做肯定是不劣的,因为有可能这些点可以连向连向它的点从而减少代价,但是入度为 \(0\) 的点肯定没救了,所以优先处理入度为 \(0\) 的点必然不劣。

所以我们删掉二元环之后做一个类似拓扑排序的操作,把对应的代价全都求出来,剩下的点就一定在环上,显然一个偶环中的点可以花费环长一半的代价两两配对,如果是奇环的话那会剩一个孤点,我们要把这个孤点和别的匹配代价 \(+1\),然后我们就做完了。

#40 Martian DNA

题意简述

给定一个字符集大小 \(|\Sigma| = K\) 的长度为 \(N\) 的字符串和 \(R\) 个要求,每个要求为使子串中的字符 \(B\) 至少出现 \(Q\) 次。求出满足所有要求的最短子串长度。

题解

水完了,双指针尺取做一下就做完了,没啥讲的不讲了。

#41. Worm Worries

题意简述

交互题,给一个三维空间,空间每个整点都有正整数点权,现在可以询问一个点点权,要求找出一个点比前后左右上下的点权都大。超出边界的点权都视为 \(-inf\)

题解

这是神秘三合一交互题,我们要对一维二维三维情况做分讨。

一维情况

考虑到假如我们肯定 \([l,r]\) 区间内假如一定有峰,我们假如询问 \(ml,mr\in [l,r]\),假如保证一定有 \(V_l,V_r\le V_{mr}\) 或者 \(V_l,V_r\le V_{ml}\) 那么一定有:

假如 \(V_{ml}\le V_{mr}\) 那么\([ml,r]\) 存在解,反之则有 \([l,mr]\) 存在解。这个是显然的,因为保证了左右端点一定小于较大的那个中间点,所以较小的中间点和较大的中间点和另一个端点之间必然存在峰值。

我们使用优选法,最开始的区间是 \([0,n+1]\)\(ml=0.382(n+1),mr=0.618(n+1)\) 显然保证了左右端点一定小于较大的那个中间点(因为 \(0\)\(n+1\) 点权都是 \(-inf\)),这样我们就能缩减区间为原来的 \(0.618\) 倍,而我们又采用了黄金分割比例,所以下一次选择的两个中间点中,其中一个就是我们上一轮选择的两个中间点中权值较大的那个,不仅满足了其中一个中间点的权值大于两个端点的权值,仍然可以复用,少一次询问次数,我们只需要花 \(1\) 次询问就能缩减区间为原来的 \(0.618\) 倍,那么我们需要的交互询问次数就是 \(\log_{\phi}n\) 的,大约是 \(29\)。算上杂七杂八的边界情况,比如不完全是黄金分割(我们选择四舍五入较接近的点)导致有所偏差,以及第一次问了两个点,还有就是最后区间大小小于 \(5\) 的时候就要终止这个优选过程,否则可能出现选的两个中间点重叠出问题,最后的这段区间我们采用暴力全询问,总之算上这些杂七杂八情况我们能在规定的 \(35\) 次以内找到答案。

二维情况

我们搞一个类似二分的操作,那么我们按照在 \(\frac{m}{2}\) 的地方画一条纵向分界线,将整个矩形分成两部分,我们一次询问这个交界线上的所有点,找到交界线上的最大点,在询问这个交界线的左右两边,如果两边都比它小,它自然就是答案,否则记录我们查询过得历史最大值,向大的一侧子矩形递归。递归过程中我们要记着将矩形一分为二的时候,类似启发式的思想,分界线采用横轴纵轴中在子矩形较小的,也就是实际上我们是横轴纵轴来回交替作为分界线问的,在之后的递归中,如果询问在分界线上的值比历史最大值大了,我们更新历史最大值,还是往比分界线上最大值大的一侧逼近递归,否则都一律按照历史最大值的那一侧递归,这样逐渐逼近,最后逼近到的点一定是我们最后询问过得历史最大值,且一定大于我们所有问过的分界线(都是问过的历史最大值了,肯定比问过的分界线大啊),自然大于他周围的所有点的,因为我们是逼近过去,他的周围我们一定全问过,所以他肯定是一个峰值,可以作为答案。

分析一下询问次数,由于我们是横轴纵轴作为分界线交替问的,所以询问整条分界线形成了等比数列一样的东西,等比数列求和算一下大概问交界线花费的询问是 \(2000\) 次,然后交界线外做一次我们最多问最大值左右(上下)两侧的两个点,而次数显然也是 \(\log\) 次的,所以大概最后的总询问次数就是 \(2000\) 带点零头,通过本题 \(3500\) 次的限制绰绰有余。

三维情况

我们先使用 \(\frac{q}{2}\) 次询问随机撒点,并且找出最大的,然后用类似爬山算法的思想,找出这个点近邻的比它大的点,并逐渐向近邻的点移动,最后不能移动了的就是答案。

我们分析一下这个做法的正确性,在随机撒点的时候,我们只要找到前 \(\frac{q}{12}\) 好的点,一次爬山最多花费 \(6\) 次询问,但是会走到更大的状态,也就是说剩下的 \(\frac{q}{2}\) 次正好够一个前 \(\frac{q}{12}\) 好的点走到最好的点,自然肯定是答案。而随机散点找不到前 \(\frac{q}{12}\) 好的点的概率显然是:

\[(1-\frac{q}{12nmk})^{\frac{q}{2}} \]

计算器算一下发现非常小,几乎就不会错误,然后这道题就彻底做完了。

#42. Alternating Current

题意简述

给一个环和若干线段,要求构造方案使得把线段划分为两个集合使得每个集合的线段都能覆盖整个环。

题解

提供一个线性做法。

我们首先判断是否存在单点被覆盖少于两次,如果存在的话显然无解,判断这个只需要差分就好了。

我们之后把环倍长,按照如下办法建图:

如果一个线段覆盖 \([l,r](l\le r)\) 我们就建一个从 \(l\)\(r+1\) 的有向边,如果覆盖的是 \([1,r]\cup [l,n](l>r)\) 那么我们就建一个从 \(l\)\(r+n\) 的有向边(我们称以上建的边为实边或者前向边)。之后若 \(i\) 点被线段覆盖了大于 \(2\) 次,我们就建 \(i+1\) 连向 \(i\) 以及一条 \(i+n+1\) 连向 \(i+n\) 的有向边(我们称这些边为虚边或者反向边)。

之后我们枚举所有点 \(i(i\le n)\),搜索是否存在一条 \(i\) 到达 \(i+n\) 的路径,若存在那么就合法,若不存在就无解。

我们考虑一下这个做法的正确性,若存在一条从 \(i\) 到达 \(i+n\) 的路径,显然这条路径上的所有实边能够覆盖整个路径,之后我们可以对这个路径做一些精简,扣去路径中被包含的边,使得路径最后大致长成这个样子:

我们发现路径不重叠的部分因为每一个点都被至少两个线段覆盖了,我们把另一个不在路径上的线段分到另外一组,那么这个点仍然在两个组都会被覆盖。至于路径重叠的部分,我们重叠部分肯定要走反向边,然而反向边存在当且仅当被大于 \(2\) 条线段覆盖,所以说重叠部分尽管我们花费了两个线段,仍然留存了一个能覆盖重叠部分的线段分到另一个组,所以依然合法。

但是注意一个细节就是可能存在 \(F=C+n\) 的情况,那么 \(C\)\(B\) 的反向边在原来的部分和倍长的部分各走了一遍,也就是说反向边走了两遍可能会存在问题,如果出现这种情况我们发现其实 \(A\)\(C\) 的边其实没必要取了,我们直接从 \(B\) 出发就能到 \(B+n\) 其不存在反向边走了两次情况,我们要记着搜完路径把这种情况判掉,把最开头的没有必要的边全删掉。

所以我们只要搜到路径,精简完路径然后踢掉没有必要的开头,实际上这道题的方案就构造完了,精简操作时间复杂度是 \(O(n)\) 的,可以参考我的代码。

那么现在我们需要想办法在线性时间复杂度搜到一条合法路径。

我们发现一个关键性质就是假如一个点 \(v\)\(a\) 搜索路径的时候走过,那么在 \(b(b>a)\) 搜索路径的时候肯定不会走 \(v\)。特别的我们只证明 \(b=a+1\) 的情况,别的情况感性理解一下其实也差不多。考虑使用反证法,假如 \(b\) 到达 \(b+n\) 需要借助 \(v\),显然假如存在 \(b+n\)\(a+n\) 的反向边,那么我们在搜 \(a\) 的时候直接借助 \(v\) 走到 \(b+n\) 再通过反向边到达 \(a+n\) 了,我们也就不会搜索 \(b\) 了,直接就找到答案了。那么如果不存在 \(b+n\)\(a+n\) 的反向边呢,假如说 \(v\) 不可以到达大于 \(a+n\) 的点,那自然也也不能到达 \(b+n\),我们不需要考虑 \(v\)。那我们如果能到达大于 \(a+n\) 的点 ,如果不存在反向边使得能够回到 \(a+n\),那么一定没有解。 \(a\) 能到达大于 \(a+n\) 的点,那么 \(a\) 显然被覆盖了两次,如果覆盖大于两次,就有反向边了,所以不能再存在任何边跨过了 \(a+n\),只有一条边跨过 \(a+n\),显然是无解的,因为这条边只能分给一个组,另一个组一定就覆盖不全了,所以如果出现这种情况,都无解了,考不考虑 \(v\) 也没有意义了。

所以我们就可以打标记了,搜过的点不重复搜索,这样每个点和边都最多只会走一次,时间复杂度是 \(O(n+m)\)

#43. Genetics

题意简述

给定 \(N\) 个长度为 \(M\) 的只由 ATGC 组成的字符串,分别编号为 \(1\ldots N\),其中一个是模式串,其它 \(N-1\) 个字符串与模式串都恰好有 \(K\) 个字符不同,找到这个模式串。

随机化乱搞套了个四进制 \(\text{bitset}\) 在洛谷上直接水过去了,可惜 \(\text{QOJ}\) 上被卡了。

题解

考虑使用和哈希,给每个字符串随机赋一个权值,然后对于每个字符串定义每一位哈希值就是和该位相同的字符串权值之和,定义一个字符串整体的哈希值就是各位哈希值之和,显然有模式串的哈希值为 \((M-K)(S-V)\),其中 \(S\) 为所有字符串权值之和,\(V\) 为自己的权值,然后判一下就做完了。

#44. Paths

题意简述

给定一个有向图,每个点有颜色,问有多少个路径包含的每个点颜色不同。

题解

太唐了,直接状压,\(dp[i][s]\) 表示路径终止在第 \(i\) 个点,经过了 \(s\) 状态表示的颜色集的方案数,然后直接正常转移就好了,注意转移顺序,先枚举状态后枚举点。

posted @ 2025-09-03 10:13  Cybher  阅读(98)  评论(0)    收藏  举报