CTS2024

Day1 T1 水镜

WC 赛时做法

考虑对于相邻的两个位置 \(i\)\(i+1\),他们之间的连通性可以用一个 \(2\times 2\) 的矩阵描述,即 \(i\) 对应的两个位置是否和 \(i+1\) 对应的位置可以连接。

发现这个 \(2\times 2\) 的矩阵只会变化一次,且变化的时刻就是 \(\dfrac{h_i+h_{i+1}}{2}\) 的时刻,那么总共变化的时刻也只有 \(O(n)\) 次。

我们在初始的时候和每一次修改一个位置的时候,可以使用线段树上二分向左右拓展,看能够拓展到哪里,每一次会得到 \(O(1)\) 个极长的区间。

把这所有 \(O(n)\) 的区间包含的区间数统计出来即可。时间复杂度 \(O(n\log n)\)

题解做法

\(p_i=\max(h_i,2L-h_i)\),发现如果段区间 \([l,r]\) 合法,说明 \(p\) 的结构形如 \(p_l>p_{l-1}>\dots>p_{k-1} ? p_{k}<\dots p_{r-1}<p_r\) 的单谷结构。

发现存在这个结构就等价于不存在 \(p_{i-1}\le p_i\ge p_{i+1}\),考虑对于 \(h_{i-1},h_i,h_{i+1}\) 之间的大小关系讨论,可以得到 \(L\) 不能属于的区间:

\(h_{i-1}<h_i\) \(h_{i-1}=h_i\) \(h_{i-1}>h_i\)
\(h_i<h_{i+1}\) \(\varnothing\) \([\dfrac{h_i+h_{i+1}}{2},+\infty)\) \([\dfrac{h_i+\max(h_{i-1}+h_{i+1})}{2},+\infty)\)
\(h_i=h_{i+1}\) \((-\infty,\dfrac{h_i+h_{i-1}}{2}]\) \((-\infty,+\infty)\) \([\dfrac{h_i+h_{i-1}}{2},+\infty)\)
\(h_i>h_{i+1}\) \((-\infty,\dfrac{h_i+\min(h_{i-1},h_{i+1})}{2}]\) \((-\infty,\dfrac{h_i+h_{i+1}}{2}]\) \(\varnothing\)

每一种情况都对应着值域的一个前缀或者后缀,那么一个区间 \([l,r]\) 不能取的 \(L\) 的集合是一个 \((-\infty,L]\cup [R,+\infty)\) 的结构,可以直接维护 \(L\)\(R\)

我们要统计所有满足条件的区间的数量,考虑双指针,但是发现双指针不好维护删除。所以考虑使用 baka's trick 可以做不删除扫描线,时间复杂度 \(O(n)\)

Day1 T2 线段树

发现线段树等价于一组三角剖分,而一个区间 \([l,r)\) 的值已知就是在 \(l\)\(r\) 之间连接一条边。如果区间 \([L,R)\) 可以被表示,等价于 \(L\)\(R\) 之间联通。

由此我们可以根据连通性设计 DP。

\(f_{i,j}\) 被线段树 \(i\) 节点(对应区间 \([l,r)\)),其中和 \(l\) 联通的编号最大的点为 \(j\) 的方案数;\(g_i\) 为线段树 \(i\) 节点,只考虑下面的边,\(l\)\(r\) 联通的方案数

通过枚举 \([l,r)\) 是否连接,可以得到如下 DP:

  • \(2g_{ls}g_{rs}\to g_i\)
  • \(g_{ls}f_{rs,j}\to g_i,g_{ls}f_{rs,j}\to f_{i,j}\)
  • \(f_{ls,j}g_{rs}\to g_i,f_{ls,j}g_{rs}\to f_{i,j}\)
  • \(f_{ls,j}f_{rs,k}\to g_i,f_{ls,j}f_{rs,k}\to f_{i,j}\)

但是在第四种转移中 \((j,k]\) 这一段不和外界联通,这也就意味着题目中要求联通的所有区间都需要满足和 \((j,k]\) 要么包含,要么不交。

考虑使用异或哈希来检验,将下标在 \([L+1,R]\) 的所有数异或上一个随机值 \(val\),如果 \(j\)\(k\) 处的权值 \(V_j=V_k\),我们才能够合并。

由于需要将 \(V\) 相同的 DP 值合并,所以可以使用线段树合并来维护,时间复杂度 \(O(n\log V)\)

Day1 T3 众生之门

通过打表发现,在 \(n\) 较大,且他的结构不是菊花的时候,答案基本都是 \(0\)\(1\),而我们可以证明答案的奇偶性,也就可以大胆猜测,答案就是 \(0\) 或者 \(1\)

所以考虑特判掉这两种情况,然后其他的情况直接随机交换检验。

考虑正确性,我们可以认为答案在 \(0\)\(O(n)\) 中随机分布,那么我们期望检验 \(O(n)\) 个就可以得到一个 \(0\) 或者 \(1\) 的结果了。

Day2 T1 多方计算

考虑一个比较直接的做法:在第一次传输的时候,第 \(0\) 个人将最低位传给第 \(1\) 个人,第一个人将这一位加在自己的数上。第二次传输的时候,第 \(0\) 个人传第二位,第 \(1\) 个人传最低位。

这样最终得到的数会是一个 \(m+\log n\) 位的数,由于最后一个人收到有 \(n\) 个时刻的延时,所以需要的时刻数为 \(n+m+\log n\)

发现在前面的时刻,后面很多的人都没有操作,所以我们可以让后面的人在这个空闲的时候也处理一些运算,比如将后面的一部分的最后几位提前加上。

原本第 \(i\) 个人在第 \(r\) 轮要传递信息是第 \(r-i-1\) 位,如果 \(r-i-1<0\),我们就然他传递第 \(r-i-1+m+\log n\) 位,发现这样我们第一轮传递的数的位数变成了 \(m+\log\log n\),只需要 \(n+m+\log\log n\),大概是 \(n+m+4\) 次传递即可。

发现距离满分差 \(1\)。既然我们可以加一轮,那么也可以加两轮,所以通过调参之后再加一轮,变成三轮加法即可。

Day2 T2 投票游戏

我们需要想一个方法快速比较两个人谁先被票出去。发现如果有一个人被票出,那么所有人的票数都不会增加,那么如果我们记录每一个人被票出的时候他的票数 \(f_i\),那么我们就可以确定那个人先被票了。

发现一个人的状态之和他的所有儿子有关,假设我们确定了当前点 \(u\) 的所有儿子的票数 \(f_i\)。将其从大到小排序,就是儿子被票出的顺序。记第 \(1\)\(i\) 个儿子的 \(b\) 值之和为 \(sum_i\),那么这个人被票出的时刻就是找到最小的 \(j\),使得的 \(a_u+\sum\limits_{v\in son_u} b_v-sum_{j-1}>f_j\),那么 \(i\) 最终的票数就是 \(a_u+\sum\limits_{v\in son_u} b_v-sum_{j-1}\),信息等价于找到第一个 \(a_u+\sum\limits_{v\in son_u}b_b>f_j+sum_{j-1}\) 的位置。使用平衡树维护所有儿子的顺序,同时维护 \(\min\{f_j+sum_{j-1}\}\) 就可以二分找到该位置。

这样做时间复杂度是 \(O(n\log n+qD\log n)\) 的,其中 \(D\) 为树的深度。瓶颈在修改,考虑使用树链剖分优化。

那么我们只用平衡树维护轻儿子,将重儿子 \(bs\) 单独拿出来讨论:我们将 \(a_u+\sum\limits_{v\in son_u}b_v\) 扔进平衡树中二分,记得到的答案为 \(ans\)。如果 \(f_{bs}<ans\) 说明重儿子不会影响到该节点被票出时的票数;否则,说明 \(bs\) 必然在 \(u\) 之前票出,票数也就会是 \(a_u+\sum\limits_{v\in son_u}b_v-b_{bs}\) 的答案。

发现当前节点的票数关于重儿子的答案,是一个分两段的常函数,可以直接维护。

发现这样每一次修改只会变化 \(O(\log n)\) 个平衡树,这样复杂度就是 \(O(n\log^2n)\) 的。

Day2 T3 字符串游戏

将字符串反转,记 \(occ(l,r)\)\(S[l,r]\)\(S[1,r]\) 中的出现次数。记 \(f_i\) 在字符串 \(S[1,i]\) 的答案,我们容易得到 DP:\(f_r=\max\limits_{1\le l\le r}(occ(l,r)-f_l)\)

对于 \(l_1<l_2\),有 \(occ(l_1,r)\le occ(l_2,r)\),则如果 \(f_{l_1}\ge f_{l_2}\),那么 \(l_1\) 处转移必然不优于 \(l_2\),这也就意味着,可能转移的决策点可以用一个单调栈维护,每一次压入 \(f_i\),将所有 \(f_j>f_i\) 弹出。

但是单调栈的大小仍然可能是 \(O(n)\) 量级的,没有对复杂度有实质上的优化。

考虑再发现一点性质。

对于 \(f_p<f_i\) 我们假设 \(i\) 的决策点为 \(q<p\),不难发现,\(f_p\ge occ(q+1,p)-f_q\ge occ(q+1,i)-f_q=f_i\),这与 \(f_p<f_i\) 矛盾,说明我们从单调栈的栈顶转移到 \(f_i\),如果当前栈顶 \(p\)\(f_p<f_i\),那么后面的转移都不需要考虑了;否则意味着 \(f_p\ge f_i\)\(p\) 需要从单调栈中弹出。

这样转移的次数就被减少到了 \(O(n)\) 次,加上计算 \(occ(l,r)\) 需要后缀树上倍增定位位置,最终复杂度为 \(O(n\log n)\)

posted @ 2024-08-08 11:02  Xun_Xiaoyao  阅读(11)  评论(0编辑  收藏  举报
/* 鼠标点击求赞文字特效 */