首页 > 其他分享 >Solution Set #2

Solution Set #2

时间:2024-06-07 09:15:39浏览次数:10  
标签:左子 连通 Set text 复杂度 Solution 考虑 节点

发电语录,被班主任注意到,并被公示到 \(\text{whk}\) 家长群了。

发电语录,被班主任注意到,并被公示到 \(\text{whk}\) 家长群了。

发电语录,被班主任注意到,并被公示到 \(\text{whk}\) 家长群了。

20.「NOI2022」冒泡排序

离散化掉 \(V_i\) 显然没有影响。

  • 基础性质:若 \(i<j\) 且 \(a_i>a_j\),若交换 \(a_i,a_j\) 后序列依然合法,则 \(a_i,a_j\) 交换不劣。证明显然:只考虑 \([i+1,j-1]\) 的点与 \(i,j\) 的影响,那么 \(a_i<a_j\) 一定不劣于 \(a_i\ge a_j\)。

由「基础性质」可以得到,未被区间限制的点单独拉出来一定构成一个不降序列。

考虑每个点都有一个下限 \(\text{lim}_i\)。可以在 \(O(n\alpha(n))\) 的复杂度,使用序列并查集优化跳跃完成维护。

【特殊性质 B/C】

考虑一个区间的限制无交,单独找出来这个区间,由「基础性质」,第一个数 \(=V_i\),并且后面保持不降,一定不劣。这个点锁定之后,考虑确定后面的值。

逆序对考虑倒着维护,放在前面的,维护后面的值。若未确定,那么令 \(c_t\) 表示 \(a_i=t\) 会向后产生多少的逆序对,那么直接取出关于限制条件的后缀的 \(\argmin\) 即可。确定之后,再去对 \(c_{a_i+1\sim m}\) 进行后缀加即可。

【特殊性质 A】

  • \(\text{min}=0\) 的意思是不全为 \(1\)。

  • \(\text{min}=1\) 的意思就是全是 \(1\)。

  • 相交且包含的第一类区间,\(I_1\subseteq I_2\) 时,需要保留 \(I_1\)。

  • 相交且包含的第二类区间,\(I_1\subseteq I_2\) 时,需要保留 \(I_2\)。

我们希望 \(a_i=1,a_j=0,i<j\) 的东西尽量少。全是 \(1\) 的限制有很多。而逆序对的关键因素是 \(0\),所以感性上少放 \(0\) 就赢了。两种限制的意思是,确定某些位置必须是 \(0\)。

倒序扫描线。考虑当且仅当不放 \(0\) 就会不合法时,再放 \(0\)。确定这些 \(0\) 后就是自由填,同样用线段树维护。

【正解】

考虑一个值 \(V\) 被若干区间限制,并且有若干点的下限是 \(V\),记这个点集是 \(S\)。我们希望这些区间导出一个具有许多更多限制的不交区间,对这些区间进行性质 A,得到必须为 \(V\) 的点值集合 \(T\)。

得到所有固定点以及每个点的下界后,套用【特殊性质 B/C】的做法。数据结构只需要维护区间加以及区间 \(\argmin\),线段树即可。

时间复杂度 \(O(n\log n)\)。

21. LOJ2552 / 「CTSC2018」假面

考虑 \(f_{i,j}\):第 \(i\) 个人剩余 \(j\) 血的概率。这个非常好维护。每次都是单点操作。

操作 2 就是求出每个人存活的概率 \(\text{alive}_i=1-f_{i,0}\)。

令 \(g_{i,j}\) 表示除了 \(i\),还有 \(j\) 个人存活的概率。答案就是:

\[\sum_{i=1}^k(1-f_{i,0})\sum_{j=0}^{k-1}\dfrac{g_{i,j}}{j+1} \]

除了 \(i\) 的限制很烦人。考虑求 \(T_i\) 表示 \(i\) 个人存活的概率。这个可以扫的时候顺便求出来。

然后 \(g_{i,j}=\dfrac{T_j-g_{i,j-1}\times (1-f_{i,0})}{f_{i,0}}\)。

随便做了,懒得算复杂度。

22. 「GDKOI-S 2023」树

如果在子树内,显然 \(\text{dis}\) 可以转化成 \(\triangle \text{dep}\)。那么在同一个 \(\text{dep}\) 的点,考虑第二维的 \(\text{dfn}\) 属性,那么我们可以考虑,求解 \(u\) 子树内 \(\text{dfn}\) 的最大值的点,减去前一个 \(u\),以容斥掉未计算的部分。每一个 \(u\) 管辖的就是每层的一段前缀。每层的最后一个点就会构成 \(u\) 子树的最右链。

令 \(\text{rs}(u)\) 表示 \(u\) 最右边的儿子,用来考虑 \(u\) 管辖的子树的边界。

定义【\(k\) 级邻域】是 \(\text{dep}_v\in[\text{dep}_u,\text{dep}_u+k)\),且在 \(v\) 的管辖范围之中的点。

考虑倍增维护,\(f_{u,i}\) 表示 \(u\) 的 \(2^i\) 级邻域的答案。考虑 \(f_{u,i-1}\to f_{u,i}\) 的变化:\(u\) 的 \(2^{i-1}\) 级的右儿子的 \(2^{i-1}\) 级邻域,在 \(i-1\) 位多异或了一个 \(1\)。还需要维护 \(\text{size}_u\) 表示 \(u\) 的管辖区域的大小,以及在此管辖区域中,有多少个点的点值在第 \(i\) 位为一。容易求出,有多少个点,在 \(i-1\) 位 \(1\to 0\),以及 \(0\to 1\)。

考虑 \(k\) 级邻域的答案,先往下跳右子到 \(v\),然后考虑从 \(u\) 往下走,去减掉 \(v\) 的管辖区域,来求出某一位的变化量。

时间复杂度 \(O(n\log n)\)。

23.「联合省选 2024」魔法手杖

记录 \(p_q\) 表示 \(p\) 在二进制表示下的第 \(q\) 位。

二分答案就是 trie 树乱搞,朴素实现判定 \(O(nk)\),总复杂度就是 \(O(nk^2)\),这样有 \(72\) 分。

二分,好像可以只存 trie 树的 \(1,2\) 度点,从而做到 \(O(n)\) 判定。弗如直接嗯贪。做法来自 @tzl_dedicatus545,膜拜。

考虑对于 \(a_i\) 建立一棵 trie 树,显然我们要从高往低确定答案。对于每个节点,记录子树中的 \(a_i\) 的 \(\min\) 以及 \(b_i\) 的和。考虑当前是处理 \(ans\) 的第 \(d\) 位,先讨论 \(x\) 的第 \(d\) 位能否是 \(0\)。

如果 \(x_d=0\),那么要想让 \(ans_d=1\),就必须把左子树全部放入 \(S\),不然 \(\text{xor}\) 出来这位就是是 \(0\),我们要保证这样做是更优的,就是令 \(ans_{t\ge d}\) 都是 \(1\),\(x_{t\ge d}\) 都是 \(0\) 时可以更优才考虑这种情况。那么把左边放入 \(S\) 就需要里面的 \(b_i\) 的和的代价,记录剩余体力然后进行判定即可。接下来就是递归右子树即可。

\(x_d=1\) 的讨论基本一致。

如果 \(ans_d\) 确定不能是 \(1\),那么可以把右边全扔进 \(S\),只考虑左子的情况,对称情况同理,接着递归即可。

最多访问 trie 树上的 \(O(nk)\) 个节点,复杂度是 \(O(nk)\)。

24.「联合省选 2024」迷宫守卫

考虑从 Alice 的视角来做这道题,Bob 在能选择的时候都会去往小的走。

这题其实是最大化字典序:

  • 给某些点用一些代价删去往右走的可能性,然后让剩下来的所有排列的最小的那个字典序最大。

考虑对于字典序最大化或者最小化的问题,逐位地确定下来答案。花了很大的代价让这一位必须更大,然后后面都改不了了,显然是更优的。

这样做,需要确定下来当前选 \(v\) 作为当前位的答案时,和前面已经确定的位造成的总贡献是否 \(\ge k\)。假设当前在对子树 \(u\) 中的点确定顺序,那么这一部分在 \(Q\) 中会构成一段区间,考虑对于 \(u\) 找出 \(u\) 中所有的叶子节点的值 \(q_v\),对其进行排序后扔进一个 \(\text{vector}\) 里面,那么我们就是要倒序判断这个 \(\text{vector}\) 里面,最先去找 \(v\) 是否合法。

Alice 要想让 Bob 第一个就去走 \(v\),肯定要付出一些代价。考虑用 \(f_{u,x}\) 表示 \(u\) 中子树的叶子节点中,Bob 到达 \(u\) 时,要想让 Bob 第一个就去走 \(x\),Alice 需要付出的最小代价。

那么其实我们必须先要求出来 \(f_{u,x}\)。突然想起来,学线段树合并优化 \(\text{DP}\) 的时候,依赖于子树叶子节点,状态数显然是对的,所以是有前途的。

令 \(\text{size}_u\) 表示 \(u\) 中的叶子节点个数,那么总状态数其实就是 \(\sum \text{size}_i=n2^n\)。

字典序这玩意只关心相对大小,那么这个 dp 也可以转化成:\(f_{u,x}\),Bob 抵达 \(u\) 时,Bob 第一个会去走叶子节点的 \(q_j\) 的第 \(x\) 小的代价。

初始状态显然是 \(f_{\text{leaf},1}=0\)。考虑对于这棵满二叉树,进行树上 \(\text{DP}\) 的状态合并。

先维护出来上文提到的那个 \(\text{vector}\),对它进行排序后,对于左子和右子分别计算其是第 \(rk_i\) 小的,可以双指针维护。

然后考虑计算 \(f_{u,i}\) 的值,需要分别讨论 \(i\) 在左还是右:

第 \(i\) 小来自于左子:

若这个位置 \(i\) 属于左子,不仅需要原来在左子的代价,而且需要保证 Bob 不会往右边跑,有两种选择:

  • 唤醒怪物,剪掉右子,代价是 \(w_u\)。
  • 对于右子排名更高的,先处理某一个,考虑让右子排名 \(>i\) 的所有的 \(\min\) 为 \(T\)。

转移为 \(f_{u,i}\leftarrow f_{\text{lson},\text{rev}(i)}+\min(T,w_u)\)。

第 \(i\) 小来自于右子:

若这个位置 \(i\) 属于左子,需要原来在右子的代价,以及不让 Bob 往左边跑,压根不用唤醒怪物:

  • 对于左子排名更高的,先处理某一个,考虑让左子排名 \(>i\) 的所有的 \(\min\) 为 \(T\)。

转移为 \(f_{u,i}\leftarrow f_{\text{rson},\text{rev}(i)}+T\)。

记录对于排名 \(>i\) 的左子的 \(f_{\text{lson},j}\) 的 \(\min\) 是 \(A\),同理设右子的是 \(B\)。倒序双指针扫一下就可以维护。

这部分的时间复杂度是 \(O(n^22^n)\),多一个 \(n\) 是因为有排序的瓶颈,也就是说要考虑 \(T(N)=2T(\frac{N}{2})+O(N\log^2 N)\)。

回到上一部分之前,考虑求出来 \(f_{u,i}\) 之后怎么做。考虑先贪心:对于当前子树 \(u\),确认接下来先去走哪里,算出来当前要去 \(v\) 的最小代价,设 \(v\) 是 \(u\) 子树中 \(q_j\) 排序的第 \(i\) 大。

在 \(u\) 里面考虑就是要 \(f_{u,i}\),但是还要考虑别的,预先已经有的代价 \(B\),以及 \(\text{fa}_u\) 不往右走做出的代价 \(w_{\text{fa}_u}\),比较上一步的信息 \(k\),如果 \(v<k\),注意到本题标号的特殊性,可以判定是哪边下来的,就需要做出来 \(w_{\text{fa}_u}\) 的代价,以保证它不往右边走。

考虑找到 \(v\) 之后,去递归处理黄色,紫色,绿色的子问题。根是从底往上去考虑。每次递归就需要预留一定的代价。递归子问题 \(t\) 的子树时,考虑从 \(B\) 中删去一些代价,当做这个子问题还未处理:当往右边递归时,额外考虑 \(w_{u_i}\),保证可以走到这里。然后都需要考虑 \(>v\) 的点 \(j\) 的 \(f_{t,j}\),这些需要取 \(\min\)。

处理好已有代价后,直接递归处理即可。正确性是最优决策不会被替换的。时间复杂度 \(O(2^nn^2)\)。

25.「联合省选 2024」重塑时光

显然要将概率转计数。

考虑对于 \(m\) 条限制建立 \(\text{DAG}\),记这个图是 \(G=(V,E)\)。直接不好算,考虑计算,对于给定的拆分方式,有多少个排列合法。这样它就变成 counting 了。

判定一组合法,考虑对于 \(k+1\) 个集合 \(S_i\),\(S_i\) 内部顺序一定是 \(G\) 对于 \(S_i\) 导出子图的拓扑序。同时 \(k+1\) 个集合之间的边不能形成环。

显然对于每个集合的内部,顺序没有太大影响,如果确定了每个集合的构成,直接乘上这些的拓扑序个数即可。记 \(g_S\) 表示 \(G\) 对于 \(S\) 的导出子图的拓扑序个数,直接枚举首位进行转移即可,这个可以做到 \(O(n2^n)\)。

定义一组集合划分的权值,是所有集合拓扑序个数以及顺序的乘积。

考虑集合之间的影响,仍然放在 \(G\) 上处理。先把空的去了,最后直接组合数一乘就行。设对于 \(f_{S,i}\) 是 \(S\) 中划分了 \(i\) 个非空集合的权值和。

音乐课想到这里想了半天不会,然后就摆烂了,wssb。

\(\textbf{DAG}\) 这种东西,一定要特殊考虑下,无入度 / 无出度 的点。

考虑钦定子集 \(T\subset S\) 使得 \(T\) 是无出度的,作为这个 \(S\) 所谓的叶子。钦定 的作用是,可以后面直接乘上容斥系数 \((-1)^{|T|+1}\),最后求和就是我们想要的东西。这个 \(T\) 中的划分方式,考虑分为了 \(x\) 个集合,这 \(x\) 个集合一定满足其是独立集,即没有边直接相连。

接下来就不难想到,考虑 \(dp_{S,i}\) 为 \(S\) 的导出子图,划分为 \(i\) 个非空独立集的所有方案的权值和,枚举子集 \(T\) 然后判定与余下部分双向独立,再转移,即:\(f_{S\setminus T,i-1}\times g_{T}\)。这个显然可以做到 \(O(n3^n)\)。

考虑回过头来求 \(f_{S,i}\),需要枚举叶子独立集 \(T\),以及其大小,需要考虑补集的所有大小,所以这部分的复杂度是 \(O(3^nn^2)\)。

算出来所有的 \(f_{S,i}\) 后,再求一下总合法方案数。再除以总方案数 \(\dfrac{(n+k)!}{k!}\) 即可。操作之间有序无序其实无所谓,因为 \(k!\) 总会被消掉。

总时间复杂度 \(O(3^nn^2)\),由于没啥常数直接就过了。

26.「联合省选 2024」季风

考虑枚举 \(m\bmod n\) 的值,会有一堆绝对值不等式,零点分段然后取个交就完事了,不用 \(\text{int128}\)。

27.「联合省选 2023」城市建造

无向图连通块问题考虑建立圆方树,用边双点双的性质去分析。

考虑将题目的限制转化成:断开 \(E'\) 中的边后,\(V'\) 中的所有点两两不连通,因此构成 \(|V'|\) 个连通块。

性质 1:若 \(u,v\in V'\),则对于所有 \(u\to v\) 的路径,其中的每个点都要选择。

为了保证 \(u,v\) 不连通,所有的路径都得被干掉。

性质 2:边双中的边同时取或者不取。

考虑一个边双连通分量中的所有边,如果并没有被取干净,那么 \(G-E'\) 会让 \(V'\) 中的某两个点,来自同一个点双的,连通。手玩可知:对一个边双,其中所有边要么全取要么不取。

性质 3:\(G'\) 本身构成一个连通块。

考虑在圆方树上刻画选择的情况,容易发现,将选择的方点染黑,那么各个连通块大小就是删去染黑方点后,各个部分圆点的个数。

由性质 3,染黑的方点一定是个连通块。

注意到连通块之差 \(\leq 1\),那么方点的连通块一定会包含,关于圆点的重心 \(R\)。那么圆方树可以直接钦定 \(R\) 为根。

令 \(\text{size}(u)\) 表示 \(u\) 子树的圆点个数。

由性质 1,2,3,可以开始圆方树上 dp 了。

注意到单层 dp 的复杂度大概率是 \(O(n)\) 的,那么我们可以考虑在最外层枚举连通块的大小。\(k=0\) 时枚举都为 \(x\),\(k=1\) 时枚举都在 \([x,x+1]\) 中,枚举量 \(O(\sqrt n)\)。

最外层在枚举 \(x\)。考虑 \(f_u\) 为在 \(u\) 的子树中删的方案数。转移时,我们把 圆方边 的情况统一放在圆点统计。

无论 \(k\),方点的方案数一定都是子节点的 dp 值相乘。

考虑圆点 \(u\) 怎么选。

\(k=0\) 时:对于 \(\text{size}(v)<x\) 的所有点,必须和这个圆点 \(u\) 绑在一起。这些 \(\text{size}\) 的和必须是 \(x-1\),否则无解。然后记录 \(\text{size}(v)\ge x\) 的所有 \(dp_v\) 的乘积就是 \(u\) 的方案数。因为这类的 \((u,v)\) 是必须断开的。

\(k=1\) 时:区别是:考虑 \(=x\) 的可以保留一个。依然是判定 \(\text{size}(v)<x\) 的子树大小和为 \(S\),\(\text{size}(v)>x\) 的 \(dp_v\) 乘积为 \(T\)。

当 \(S=0\) 时,可以将 \(u\) 扔进 \(=x\) 的连通块,可以有额外贡献,有以下讨论:

对于 \(\text{size}(v)=x\) 的:考虑一共有 \(c_1\) 个,其中有 \(c_2\) 个不能单独放,也就是 \(dp_v=0\) 的一共有 \(c_2\) 个。显然 \(c_2>1\) 时就寄了,当 \(c_2=0\) 时,直接是 \(T\times c_1\),否则当 \(c_2=1\) 时,有 \(T\) 种。

然后再乘上正常分讨:将 \(u\) 和 \(\text{size}(u)<S\) 的点 \(v\) 的扔一起的方案数。

  • 对于 \(k=0\),时间复杂度 \(O(nd(n))\)。
  • 对于 \(k=1\),时间复杂度 \(O(n\sqrt n)\)。

28.「NOI2023」桂花树

条件 \(1\) 等价于 \(1\sim n\) 在 \(T_2\) 的虚树就是 \(T\),换而言之,所有的 \(n+1\sim m+1\) 就是在 \(T\) 上面「生长」出来的,可能是 \(T\) 上的枝条「分化」出了节点,然后在这些节点上开花。也有可能是在 \(T\) 的节点上「分裂」出节点。

  • 所以为什么我生物 \(1.333\) 模比一模低了 \(10\) 分???

考虑条件二。很不好考虑,注意到 \(k\) 很小,提示我们去往 \(2^k\) 上去想。

\(\max\) 这个东西考虑强制钦定一维大于另一维。

考虑扫描线地从小到大加入节点 \(i\in [n+1,n+m]\),那么所有原有的节点 \(j<i\) 都需要满足 \(\text{LCA}(i,j)\leq i+k\)。

考虑 \(k=0\) 的部分分怎么做。

  • 在树上逐渐插入 \(n+1\sim n+m\) 的所有点,注意到所有的节点都需要与 \(i\) 在更小的节点相聚。那么 \(i\) 只能插入在每个边的中间,即「分化」,也可以直接「分裂」在某个点的下面。

  • 每次都是同样的问题:已有 \(S\) 大小的树,可以插入在 \(S\) 个点下面,或者 \(S-1\) 条边中间。有 \(2S-1\) 个选择。

因此答案就是:\(\prod_{i=n}^{n+m-1}(2i-1)\)。

考虑 \(k>0\) 的问题是什么:

有些节点可以与 \(i\) 在更大的节点相聚。但是我们不能让直接让 \(i\) 挂在半空中,需要提前加入一个标号更大的点使得 \(i\) 与这棵树连通。

因此可以考虑虚树。我们只需要对虚树计数。每次的操作只有以下三种,并且当前已经至少加入 \([1,i-1]\) 的点:

  • 挂在已有边上。进行「分化」。
  • 挂在已有点上。进行「分裂」。
  • 在已有边上,先分裂出一个标号更大的点 \(u\),作为 \(i\) 与某些点的 \(\text{LCA}\),然后再直接把 \(i\) 挂在 \(u\) 下面。

注意到 \(k\leq 10\),因此可以考虑当前虚树的形态为 \([1,i]\cup S\) 中的点构成,其中 \(S\subseteq[i+1,i+k]\)。可以直接状压 dp 维护方案数。

时间复杂度 \(O(Tmk2^k)\)。

标签:左子,连通,Set,text,复杂度,Solution,考虑,节点
From: https://www.cnblogs.com/nullptr-qwq/p/18236460

相关文章

  • Solution Set #1
    最近不想写题。1.P8456简单题。显然要容斥计算同色路径的个数。无向图路径问题,考虑把边双缩点,建立圆方树。不难想到对每个方点分类:全D,全d,有D有d。并查集维护每个全D,全d极大连通块的大小即可。这样会算多。考虑\(x-y,y-z\)为D,\(z-x\)为d的三元环,这会形成异色方......
  • Solution Set #4
    搬了以前的博客。大概都是\(2023\)年做的。38.P5369状压最大前缀和的集合。dp算一下符合条件的集合,要求任意后缀和\(\ge0\),枚举结尾元素转移即可。后面的就是任意前缀和\(<0\)。39.「联合省选2021A|B」图函数\(f(u,G)\)含义,有多少\(v\)满足存在\(u\rightarrow......
  • Solution Set #5
    开始补\(3\)月的做题。102.P7417由于\(f_G(a,b)\)可以走重边,所以我们只关心奇最短路以及偶最短路。判掉一下每个点只有奇数路径或偶数路径,即二分图,可以直接最短路树,在两题都需要特判掉。本题的重点在于确认\(G'\)的结构。考虑\((x_i,y_i)\)为不同奇偶的最短路数对,要......
  • CF1913C Game with Multiset
    题目Inthisproblem,youareinitiallygivenanemptymultiset.Youhavetoprocesstwotypesofqueries:ADD\(x\)—addanelementequalto\(2^{x}\)tothemultiset;GET\(w\)—saywhetheritispossibletotakethesumofsomesubsetofthecur......
  • 报错 urllib3 (1.26.7) or chardet (5.2.0)/charset_normalizer (2.0.8) doesn‘t mat
    报错RequestsDependencyWarning:urllib3(1.26.7)orchardet(5.2.0)/charset_normalizer(2.0.8)doesn'tmatchasupportedversion!warnings.warn("urllib3({})orchardet({})/charset_normalizer({})doesn'tmatchasupported"这个警告信息Req......
  • memset函数
    转载:https://www.cnblogs.com/-wenli/p/11491127.htmlC语言memset函数详解memset()的作用:在一段内存块中填充某个给定的值,通常用于数组初始化与数组清零。它是直接操作内存空间,mem即“内存”(memory)的意思。该函数的原型为:#include<string.h>void*memset(void*s,intc......
  • goto 语句以及 setjump、longjump 函数的注意事项总结
    关于goto、setjmp、longjmp的注意事项,总结如下:goto语句避免滥用:goto语句虽然能够提供一种直接的跳转方式,但过度使用会使程序结构变得复杂,难以阅读和维护。应优先考虑使用结构化的控制流语句(如if、while、for等)。防止死循环:在使用goto语句时,要特别注意不要形成死......
  • 靶机练习:sunset: midnight
    信息收集扫全端口和服务80端口直接访问访问不了:/wp-adminhttp://sunset-midnight看到域名先进行域名绑定,编辑/etc/hostsipsunset-midnight绑定后可正常访问,访问robots.txt文件访问/wp-admin,存在wordpress服务使用wpscan扫描地址[+]WordPressversion5.4.......
  • network xxx was found but has incorrect label com.docker.compose.network set to
    在执行docker-composedown之后,再执行docker-composeup-d提示已有同名称标签的虚拟网卡  解决1、执行dockernetworkls命令展示所有的虚拟network2、执行dockernetworkrm<networkId>删除已存在的network3、再重新运行docker-composeup-d启动容器  扩......
  • android12 Settings 添加导航栏和状态栏开关
    平台RK3568,android12添加导航栏和状态栏的开关。 通过设置系统属性来默认系统关闭导航栏和状态栏。Index:device/rockchip/rk356x/device.mk===================================================================---device/rockchip/rk356x/device.mk(revision2442......