CSP-S 历年题集

I 2019

D1 T1 格雷码

简单模拟,翻转只需减一下即可。

代码

D1 T2 括号树

我们令 sx 表示以 x 点为结尾所能构成的合法序列的方案数,则我们可以在树上括号匹配,若点 x右括号且匹配的左括号u 点,则有 sx=sfau+1,最后每个节点的答案即为树上前缀和。

代码

D1 T3 树上的数

贪心 + 思维。部分分对于正解有启发作用。

暴力 10pts。

首先我们考虑贪心,从小到大枚举每一个数字,尽可能的让每个数字到达的点编号最小,所以我们只需要考虑是否可以使某个数字从 uv 即可。

菊花图开始,可以发现,删边顺序使节点间构成了一个环,我们可以用并查集维护这个环。

的部分比较难,对于一个点最多只有三种删边情况,即 先删左,先删右,未删,对于一个 uv 的路径,不妨设 u<v,我们发现。

  • 对于 u,需要满足该点必须为先删右
  • 对于在 u,v 中间的节点 p,需要满足该点必须先删左
  • 对于 v,需要满足该点必须为先删右

这样我们可以 O(n) 判断是否可以满足条件,结合贪心即可。

对于一般的树,对于每个节点,相当于我们有一些先后关系,需要判断是否满足条件。不像一样,我们只有少数情况,这些先后关系是及其复杂的。

这种先后关系我们可以用并查集/链表维护。

假设我们要 uv,我们逐个讨论:

  • 对于 u,需要满足这个路径上的第一条边 w 是该点最先删除的。详细一点,需要满足:
    • 该点最先删除的边为 w
    • 不能有边在其前面删除。
    • 不能在已经维护好起点与终点所有顺序关系后还存在边未被删除
  • 对于 v,需要满足这个路径上的最后一条边 w 是该点最后删除的。即:
    • 该点最后删除的边为 w
    • 不能有边在其之后删除。
    • 不能在已经维护好起点与终点所有顺序关系后还存在边为被删除
  • 对于 u,v 中间节点 p,该路径上的两条边 w1w2先后顺序是必须相邻顺序的。即:
    • w1 之后的不能有边,w2 之前不能有边。
    • w1 不能是最后删边,w2 不能是最先删边。
    • w1w2 不能已经被删边。
    • 不能在已经加入两边后,使得维护好起点与终点顺序关系后还存在边未被删除

这样我们从小到大枚举数字,再从小到大枚举节点,判断是否可行,这样复杂度是 O(n3)

只需要以某个点为根,遍历整棵树,找出符合要求的最小节点编号,这样复杂度是 O(n2logn) 的。

细节多,思路厉害,是好题。

代码

D2 T1 Emiya 家今天的饭

限制 3 比较强,可以发现一个性质:若有满足不符合要求的方案,则有且仅有一种主要食材不符合要求。则我们可以求出不符合要求的方案数,总方案数减去可得答案。

这样我们枚举主要食材w,让其作为不符合要求的食材。

则我们设 fi,j,k 表示前 i 种烹饪方式中,选用了 j 种烹饪方式(满足性质 2),且其中有 k 种是用 w 烹饪的。

则有转移方程 fi,j,k=fi1,j,k+fi1,j1,k×(siai,w)+fi1,j1,k1×ai,w,其中 si=ai,j

则不符合方案数即为 k>j2 的 DP 值,这样复杂度是 O(mn3),84pts。

我们考虑优化,可以发现,我们不关心 jk 的真实值,我们只关心是否 k>j2。移项得 2×kj>0,即我们只关心这个值,我们可以消减状态,设 fi,u 表示前 i 中烹饪方式中,使得 2×kj=u 的方案数。

则有转移方程 fi,u=fi1,u+fi1,u+1×(siai,w)+fi1,u1×ai,w

复杂度 O(mn2) 可过,注意 u 可能为负数,需要加一个偏移量。

代码

D2 T2 划分

首先有 O(n3) 的简单 DP,不过与正解无关。

对于 s1s2,当 s2 最小时,s12+s22 最小。

这样我们设 fi 表示选择 [fi+1,i] 中的数组成一组数据,可以取得最小贡献,则我们可以贪心的选择尽可能靠右的决策点,可以 O(n2) DP。

符合要求的决策点有 sisjsjsfj,即为 si2×sjsfj

我们可以单调队列优化,复杂度 O(n),不过输入真逆天。

代码

D2 T3 树的重心

我们考虑每个节点 x 所造成的贡献,设删去一条边所减去的节点数为 S,则我们需要分讨是否在节点 x 的最大子节点内。

这样是不好做的,我们考虑选择一个节点作为,来去除这些麻烦,我们需要使最大节点固定,这样我们可以选择以原树的重心为根,这样除根以外的其他节点的最大节点都朝向根,即对于这些节点 x,删除其子树内的边不可能造成该点的贡献,这样我们就方便了许多。

这样我们对于除根以外的点 x,要使 x 节点为根,需要满足 2×sxnS 以及 2×(nsizxS)nS 其中 sx 表示 maxyxsizy

移项可得 n2×sizxSn2×sx

则我们只需要用树状数组求出即可,而对于 x 子树内的边可以用树状数组在进出该点时相减一下即可,减去这些贡献即可。

最后我们只需要暴力考虑根节点所造成的贡献即可,即分讨一下再判断即可。

复杂度 O(Tnlogn)

代码

II 2019 江西重赛

T1 日期

暴力分讨即可。

代码

T2 和积和

我们考虑枚举 i,设当前 si 表示 r=i 所有 l[1,i] 的和,可以发现,当我们 i 增加时,相当于 A×B(A+ai)×(B+bi)=AB+Abi+aiB+ab

我们考虑每个式子,首先有 AB=si1A 即为所有前面 a和的和B 同理,ab 共出现了 i 次(因为有 i 个式子)。

则有 si=si1+bi×j<ij×aj+ai×j<ij×bj+i×ai×bi

简单维护即可,复杂度 O(n)

代码

T3 网格图

考虑 Kruskal 的本质,即为贪心枚举边权,以及防止成环,则我们可以 a,b 排个序,对于横线,我们考虑那些边不能连,可以发现是与 当前已加竖线条数 相关的。竖线同理。

复杂度 O(nlogn)

代码

T4 散步

我是历史学家,这就是史。

代你码

T5 多叉堆

考虑对于一棵树 x,新加入一个子树 y 的贡献,首先需要满足 x 节点最小,可以发现这些 size[0,sizex+sizey) 是等价的,即它们只有大小关系,具体数值是不重要的,所以我们可以得出 fx=(sizex+sizey1sizey)fyfx,即在这些数中选 sizey 个分配给 y 子树。

对于合并可以并查集维护。

复杂度 O(nα(n))

代码

posted @   oXUo  阅读(56)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
网站统计
点击右上角即可分享
微信分享提示