2025 上海集训随机记录

联考 D1T2

  • Floyd 算法,寻找性质。

先猜一手有用的最终可能涉及到的 \(h\) 一定就是原来 \(h\) 序列的所有数,写一发 \(\mathcal O(n^4\log n)\) 发现过了 \(45\) 分,感性理解是再调整一定优秀。那么考虑确定 \(s\to t\) 路径以及计算 \(w\) 的贡献后如何调整 \(h\)。令路径上 \(u\) 的高度变为了 \(h_u'\),那么考虑按序写出后 \(h'\) 的极长相等连续段。给出结论:对于每个连续段中一定有至少一个是固定的。这是因为对于一个代价函数其是若干分段一次函数求和,拐点只由 \(h\) 来决定。

那么称 \(h'=h\) 的点为关键点。注意到正解大概率是 \(\mathcal O(n^3)\) 的 floyd 算法,那么应该处理的是:

  • 关键点 \(u\) 直接到关键点 \(v\) 的最小代价 \(d(u,v)\)
  • 关键点 \(u\) 可以间接走若干转移最终到关键点 \(v\) 的最小代价 \(c(u,v)\),可以直接对 \(d\) 执行 floyd 算法得到。
  • 起点 \(x\) 到关键点 \(u\) 的最小代价 \(g(x,u)\),关键点 \(u\to v\) 的最小代价,关键点 \(v\) 到终点 \(y\) 的最小代价。可以分步转移为 \(x\to v,v\to y\),同样可以 \(\mathcal O(n^3)\)

考虑如何处理 \(d\)\(u\to v\) 的路径上满足包含 \(u\) 的一段前缀被染为 \(h_u\),那么剩下包含 \(v\) 的后缀就被染为 \(h_v\)。由于你最后还要处理一个 \(g\),考虑让 \(g\) 来求 \(d\)。你对 \(g\) 执行求答案的过程类似的分步转移可以用 \(g\) 来求 \(d\)。那么现在要求 \(g(u,v)\)\(u\) 走到 \(v\)\(u\to v\) 路径上全部染成 \(u\) 颜色的最小代价,这个其实是朴素的,枚举起点 \(u\) 然后使用 \(\mathcal O(m+n^2)\) 的 dijkstra 算法即可。这样跑 \(n\) 次就可以求出所有 \(g\)。总时间复杂度 \(\mathcal O(n^3)\)

P5609

  • 线段树维护函数复合。同一函数的形式上的灵活变换。

当前的 \(res\) 可以表示为,记录当前的真实和为 \(sum\),那么有 \(res=sum-kp\)。当加入一个新数时,若 \(sum\ge (k+1)p\),则有 \(k'=k+1\),否则 \(k'=k\)。那么考虑使用线段树来维护整个数列对于此的线性变换。注意到 \(a\) 是静态的,那么考虑维护这个线性变换经过一个区间 \([l,r]\) 的信息。然后线段树的区间 \([l,r]\) 是可以维护 \(r-l+1\) 个信息的,因此考虑维护减 \(kp\) 这个信息。原先对于区间 \(I\) 有函数 \(f(x)\) 表示初始传入 \(x\) 后减去了多少个 \(p\),现在可以转化为至少传入 \(g(k)\) 后就会减去 \(kp\)。此处 \(k\in[0,r-l+1]\)。信息的空间复杂度是可以接受的 \(\mathcal O(n\log n)\)

然后考虑信息合并即二区间函数复合,此处对于一个长度为 \(len\) 的区间定义 \(g(len+1)=\infty\)。那么对于一个 \(x\in[Lg(k),Lg(k+1))\) 而言,经过左边区间就会变为 \(x+sum_{lson}-kp\)。那么考虑其在右侧减了 \(qp\),根据这个 \((k,q)\) 以及 \(Rg(q)\),算出这样的 \(x\) 的下界,贡献(取较小值)到整个区间的 \(g(k+q)\) 上。解出 \(x\in[\max(Lg(k),Rg(q)+kp-sum_{lson}),Lg(k+1)-1]\)。整体是取 \(\min\) 的,感性理解一下,\(\Delta Rg\ge p\) 因此内层的那个东西是有单调性的,可以双指针优化合并,时间复杂度优化到线性合并,那么总复杂度就是 \(\mathcal O(\log n)\),而不是 \(\mathcal O(\log^2n)\) 的合并。

对于询问 \(x\) 的变换,在经过一个完整的区间时对于 \(g\) 进行二分,这一部分就是 \(\mathcal O(m\log^2n)\),由于 \(m\) 较少可以接受。因此总时间复杂度 \(\mathcal O(n\log n+m\log^2n)\)

P7155

  • dp 阶段划分,分步转移,前缀和优化。

读完之后感觉这个题会有无限递归,但其实并不是的。你发现操作了 \(n\) 之后 \(n\) 就无法再操作了,递归到子问题上,因此是有穷的。构造形如 \(n-1,\cdots,2,1,n,\cdots\)。这也启示我们按照当前被操作的最高数位进行阶段划分。一个基础的划分思想是,划分成若干极长连续单调递减子串,然后考虑这些子段的起点,我们发现其不是前缀 \(\max\) 的起点其实严重到,前面那个最近的前缀 \(\max\) 开始的操作序列的影响,因此你的划分是前缀 \(\max\)。总之,你对于一个操作序列而言,关心的应当是前缀最大值。显然一个前缀 \(\max\) 对后续就是一个崭新的阶段。注意本题保证了前缀 \(\max\) 就是严格前缀 \(\max\)。然后对于每个前缀 \(\max\) 内部的部分,我们也满足这个递归的性质。这很像【集训队互测 2023】序列。进一步的,你甚至关心的是全局 \(\max\),这样就可以拆成左右两个子问题。

那么就有一个状态设计就是 \(f(s,t,p)\) 表示在 \(s\to t\) 的序列按下的最大值为 \(p\) 的方案数,枚举位置然后递归即可。然后对于询问拆点,使用前缀和优化。视 \(n,k,q\) 同阶,时间复杂度 \(\mathcal O(n^4)\)。对于询问的处理方式是一个分步转移状物。

联考 D1T3

  • 格路计数,反射容斥。

\(f(A)\) 可以改写为,把 \(0\) 看作 \(−1\)\(1\) 看作 \(1\),序列前缀和的极差。这是因为可以考虑划分的 \(01\) 交替子序列的数量。设 \(g(a,b)\) 为上限是 \(a\),下限是 \(−b\) 时的合法序列个数,设 \(G(m)=\sum g(i,m−i)\),可以发现 \(G(m)−G(m−1)\) 就是 \(f(A)≤m\)\(A\) 个数。因此只需求出所有 \(G(m)\) 即可求出答案。这是因为一个方案减完就恰好会贡献 \(1\) 的系数。可以发现 \(G(m)\) 其实等价于,不能碰到 \(y=m+1,−1\) 两条线,起点从 \((0,0)\)\((0,m)\) 任取,终点从 \((n,0)\)\((n,m)\) 任取,合法格路的总条数。可以同时翻折所有起点,这样能做到 \(\mathcal O(n\ln n)\),这是一个经典的两直线间的反射容斥。

联考 D2T1 / CF720C

这是 *3100???考虑构造题的经典思路,调整法。先逼近一下 \(k\),顺着填就好。然后对于填到的终点位置对于离它比较近的位置随机调整即可。赛时写的是爆搜,倾向于将点涂黑,已有 \(>k\) 就退出。跑的层数很多仍未出解时宣布无解。这样做的道理是,定义搜索树左子树为保留 \((x,y)\),右子树不保留 \((x,y)\),由于倾向走左侧相当于就是在最底下几层做爆搜,上面往下走的过程一直在走左边。所以跑很快。

学习支配树

考虑一张有向图 \(G=(V,E)\) 以及一个关键点 \(s\)

  • 定义 \(u\Rightarrow v\) 当且仅当任意一条 \(s\to v\) 的路径都经过 \(u\),称 \(u\) 支配 \(v\)。这个关系是偏序关系。
  • 性质:如果对于 \(u\) 有不同的 \(v,w\) 使得 \(v\Rightarrow u,w\Rightarrow u\),则有 \(v\Rightarrow w\) 或者 \(w\Rightarrow v\)

由偏序性质以及上述性质,可以构建一个支配树:满足 \(u\) 的父亲 \(fa(u)\) 满足 \(fa(u)\Rightarrow u\) 且不存在 \(k\ne u,k\ne fa(u)\)\(fa(u)\Rightarrow k,k\Rightarrow u\)。也就是说 \(fa(u)\) 就是 \(u\) 的唯一的(最近)支配点。

【DAG 支配树的构造】

  • 对于 \(u\ne v\),有 \(u\Rightarrow v\) 当且仅当对于任意边 \((w,v)\in E\)\(u\Rightarrow w\)

那么考虑按照拓扑序进行构造,对于 \(u\) 其支配树的父亲就是所有对于 \(u\) 的入边 \(w_i\),考虑 \(w_i\) 在已有支配树的 \(\text{LCA}\)。使用动态树上倍增维护即可。

【一般有向图支配树的构造】

首先对原图进行 dfs 求出 dfs 序以及 dfs 生成树 \(T\)。称 \(u<v\) 当且仅当 \(dfn_u<dfn_v\),同理定义 \(>\) 关系。令 \(f_u\) 表示 \(u\)\(T\) 上的父亲。

  • 定义 \(u\) 的半支配点 \(v=sdom(u)\) 为一个 dfs 序最小的点 \(v\) 使得存在一条 \(v\to u\) 的路径 \(p_i\) 使得对于 \(p_i\ne u,p_i\ne v\) 都有 \(p_i>u\)

先考虑怎么求解半支配点。考虑 \(u\) 的入边 \((v,u)\),如果 \(v<u\)\(v\) 有可能成为 \(sdom(u)\),如果 \(v>u\) 那么考虑所有 \(v\)\(T\) 上的祖先 \(k\),如果有 \(k>u\) 则有 \(sdom(k)\) 有可能成为 \(sdom(u)\)。那么由 dfs 序倒着考虑,那么考虑到 \(u\)\(v>u\)\(v\) 就是已经插入的。在此过程维护一下带权并查集,将 \(T\) 上祖先合并一下,可以 \(\mathcal O(n\log n)\)\(sdom\)。现在考虑用 \(sdom\) 求出 \(dom\)。求出在 \(T\) 上对于 \(u\)\(sdom(u)\) 上链的 \(x\)\(sdom(x)\) 最小的点 \(x\) 以及 \(y=sdom(x)\)

  • \(sdom(u)=y\),则有 \(dom(u)=y\)
  • \(sdom(u)>y\),则有 \(dom(u)=dom(x)\)

可以在维护 \(sdom\) 的过程中同时维护 \(dom\)。时间复杂度 \(\mathcal O(n\log n)\)

P9052

  • 图论,支配树思想。

枚举 \(B\) 随便记录一下路径最值有一个 \(\mathcal O(n^2)\) 的做法。大概就是,拓扑排序,每次从 \(B\) 开始不断删除无出度的节点。转化一下,保留图上所有标号 \(\leq k\) 的点,题意可以变为 \(A\) 开始的任意一条路径均经过 \(B\)。那么这基本就是一个支配树的题。考虑先做 \(k=n\)。观察一下合法的关系 \((A,B)\) 所具有的性质。传递性是显然的,即 \((A,B),(B,C)\Rightarrow (A,C)\),但还有一个重要性质是,我们仿照支配树的性质 \(2\) 可以设计出:若 \(A\Rightarrow B,A\Rightarrow C\) 则有 \(B\Rightarrow C\) 或者 \(C\Rightarrow B\) 成立。那么我们可以构建支配树状物,对于 \(u\) 选取最近的支配点来建树。注意这棵树事实上是一个基环树。

先考虑求 \(k=n\) 的答案。考虑支配树的根 \(root\),也就是说考虑最开始删掉点 \(root\)。我们令 \(S_{root}\)\(root\) 删除掉的点集,我们希望刻画 \(S_*\) 之间的关系。模仿 P8276 的套路,对于一种朴素情况,\(u\) 的出边有且仅有 \(v\),那么考虑直接删掉 \(v\) 会导致 \(u\) 被删除,\(u\) 就是没有用的,那么令 \(u\) 的所有入边改接到 \(v\) 并叠合重边,注意自环需要保留。那么重复这个过程直到最终任意点出度 \(\ge 2\),此时删除任意一个点都不会导致进一步的删除。此时图中的每个点都可以成为一个根或一个支配基环树环里的某个点。那么一个点代表的 \(S\) 一定是极大的,且两两不交,是全集的一种划分。那么这些点相当于支配树的根的点集。

观察一下支配树是什么,考虑找出 \(u\) 的支配点,一个点 \(u\) 的支配点就是所有出度在支配树上当前的 \(\text{lca}\)\(dom(u)\)。那么就将 \(u\) 挂在 \(dom(u)\) 之下。注意根可能支配自己,也有可能是一个形成环。此时对应的是,删除掉自己之后不断删,把环删干净了,最终把整个支配树都删了。对于一个不在环上的,只能删除其子树。也就是说一个点的支配点被删之后由其定义他自身就会被删除。用上文操作把 \(k=n\) 的基环森林给求出来,统计一下信息就可以做 \(k=n\)。形式化地说,求出基环森林上可达点对 \((x,y)\) 的数量,即为 \(k=n\) 的答案。维护缩图的过程可以使用线段树合并,用队列维护删掉的点。

由部分分提示,先建立 \(k=n\) 的基环森林,一条边出现后就不会消失,在建树过程维护一下出现时刻。那么考虑刻画为基环树的 \(\text{dfs}\) 生成树加上有且仅有的一条返祖边。此时我们可以不妨设根是返祖边的端点,而返祖边可以设置为出现时刻最大的点。对于当前已经加入的点和边,并查集维护大小和最浅的点可以支持计算不经过返祖边的答案。时间复杂度 \(\mathcal O((n+m)\log n)\)

联考 D3T1

考虑先处理出每个位置的上下界 \([l_i,r_i]\),以及每个值的出现位置区间 \([p_v,q_v]\)。那么放到二维平面上处理,扫描线加入点,那么相当于一些区间内可存在的点连边,可以主席树/线段树优化建图。时间复杂度没有保证。\(\mathcal O(n^3/w)\) 的暴力 bitset 优化二分图过了。

联考 D3T2

先注意到 \((a,b)\) 以及边长为 \(1\) 的和是 \(Fib_{2a-b+???}\)\(???\) 是一个常数,因为这个左对齐杨辉三角有些许神秘位移。那么考虑对这个询问进行二维前缀和状物的优化容斥。要求的其实是一个奇偶项 \(Fib\) 前缀和,就是 \(Fib\) 的前缀和加减上一些常数。可以矩阵快速幂快速求某个 \(Fib\) 的单点值。时间复杂度 \(\mathcal O(kT)\)

联考 D3T3 / QOJ8806

  • \(01\) trick 的运用,树上 dp。

首先判掉 \(A\leq B\),因为这样 Bob 无论如何都可以反悔掉 Alice 的任意决定,自然也就可以按照自己想的取到节点 \(1\)。下面默认 \(A>B\),首先考虑多项式复杂度做法。注意到深度是不断下降的,完整的一轮结束后走到某个根的子树内就再也不会出来。\(f_{u,v}\) 表示下一步是 Alice 当前走到节点 \(u\),禁止走向节点 \(v\) 的子树。\(v=0\) 表示不存在,这个状态数是线性的。然后对于树上距离恰好为 \(A\)祖先对可以暴力预处理出,总对数是线性,一个在下面的节点只会在其 \(A\) 级祖先(若存在)贡献恰好一对。那么就有一个 \(\mathcal O(n^3)\) 的转移,枚举 Alice 走到 \(p\),Bob 走到 \(\text{dis}(p,q)\leq B\) 后转移。这样是没什么救的,转移带 \(\max,\min\)。链就是这个东西放到数轴上,线段树优化 dp 即可。这些拼起来有 \(40\sim 52\) 分。

问题的瓶颈在于 \(\max,\min\),不难想到的一步是进行二分答案 \(mid\),将 \(\leq mid\) 的点标记为 \(1\),标号 \(>mid\) 的点标为 \(0\)。那么 Alice 的目标就是走到 \(0\)。此时 \(f\) 的值域就是 \(\lbrace0,1\rbrace\)。然后考虑类似分步转移的一个东西,我们的转移不应该同时枚举 Alice,Bob 的决策。但注意到 Alice 的总决策数线性,那么其实还是有救的。设计这样几个东西,我们按照节点深度从大到小维护就是正确的:

  • \(f_u\):只考虑 \(u\) 子树,Alice 开始从 \(u\) 操作,最终能否走到一个 \(0\) 上。如果 Alice 在 \(u\) 无法操作,那么就考虑 \(u\) 子树中距离 \(u\)\(\leq B\) 的点中是否有 \(1\)
  • \(g_u\):只考虑 \(u\) 子树,认为 \(R\to u\) 的路径均被染黑,Bob 开始能否走到一个 \(1\) 上。
  • \(h_u\),其实就是暴力过程中的 \(f_{fa(u),u}\):当前走到 \(fa(u)\),不允许往 \(u\) 走,Alice 操作,能否走到一个 \(0\) 上。

\(h\) 的维护与 \(f\) 相似。\(g\) 的维护需要考虑子树内最近的 \(f_u=0\) 的点,与祖先中的信息。可以发现,\(f,g,h\) 三个数组的更新可以按照节点深度从大到小更新。上述维护的瓶颈在 \(g\) 的祖先的信息,这部分可以将贡献拆开,在 \(\text{dfs}\) 序上用线段树维护最值。考虑最外层的一个二分,时间复杂度 \(\mathcal O(n\log^2n)\)。代码实现细节上,我们逐层处理,当处理到深度为 \(d\) 时我们可以维护 \(d+A\) 深度所有点的真实值,向线段树插入 \(d+A-B+1\) 深度所有点的信息。也就是线段树要做的时维护祖先反悔跳向另一个子树的信息。

模拟赛 R5T3

  • 动态点权的树上带权重心。

考虑如何进行询问,找到树的带权重心 \(rt\),然后把 \(rt\) 当成根。如果 \(rt\) 可以被选,则必然选 \(rt\),否则,如果选择 \(rt\) 之外的点 \(k\),那么流量就是子树 \(k\) 以外的 \(\sum c\),要最小化流量,就是找一棵除了根以外的子树使得子树内的 \(\sum c\) 最大。

先考虑在 \(c\) 有修改时维护 \(rt\):不妨设树根为 \(1\)。求出权值和 \(sum\),等价于一个点为根,所有子树大小都 \(\leq \lfloor sum/2\rfloor\)。 然后找重心还有经典结论就是往最大的子树走。对于从一个点出发,往上快速跳是简单的,只需要跳重链,然后在重链上二分就可以了。但是快速往下跳是不好做的。为了防止出现往下走的情况,我们需要选择合理的往上跳的起点。具体地,找到第一个点 \(p\) 满足 dfs 序 \(\leq\) 它的点的权值和 \(\ge\lfloor sum/2\rfloor+1\),发现以 \(p\) 作为起点就一定不会出现往下走的情况。

对于 \(k\) 不在 \(1\)\(rt\) 路径上的情况,因为以 \(rt\) 为根和以 \(1\) 为根的情况是一样的,相当于是维护,除了 \(rt\)\(1\) 路径上的点以外,其它点的子树大小的最大值。而对于 \(k\)\(1\)\(rt\) 路径上的情况,当然就应该选 \(rt\) 的祖先中离 \(rt\) 最近的可选点。树链剖分维护上述过程,时间复杂度 \(\mathcal O((n+m)\log^2n)\)

P5547

首先考虑对无标号有根树计数。\(f_{n,0/1/2}\) 分别表示树根为红,蓝,黄且树的大小为 \(n\) 的方案数。由于需要考虑度数,那么还有一个 \(g_{n,1/2/3/4}\)\(1/2/3/4\) 棵树大小总和为 \(n\) 的方案数。同时记录一个 \(h_{n,1/2/3}\) 表示树根均不为黄色的方案数。由 \(g/h\) 推得 \(f\) 是容易的。考虑求 \(g/h\)。注意到 \(f\) 是基于 \(g/h_{n-1,*}\) 来统计的,那么可以通过 \(f_n\) 反推 \(g/h_{n}\),那么枚举这其中有多少是 \(n\) 的,乘以一个组合数即可,需要暴力做。时间复杂度 \(\mathcal O(n^2)\)

然后考虑无标号无根树,考虑对这种树哈希的经典 trick:无标号无根树的重心有且仅有一个,那么我们要求计数的树根恰好是构成树的重心。那么我们就要求任意子树大小 \(\leq n/2\),偶数且一边子树大小恰好为 \(n/2\) 的会算两次容斥一下即可。

联考 D4T1

  • Hall 定理来进行分析,线段树实现具体操作。

考虑怎么判无解:直接顺着扫描线一遍,每次填写未被填入的且可以填的数中 \(r\) 最小的数,某次没法填了就是无解。然后这个题其实是 Hall 定理,令左部图是值,右部图是位置,那么每个值会向对应位置区间的右部图的点进行连边。我们要求对于左部图存在完美匹配,就要求 \(\forall S\subseteq L\),有 \(|S|\leq |N(S)|\)。那么发现 \(N(S)\) 是一个区间时是最强的限制,令 \(w(l,r)\) 表示有多少个位置对应的区间被 \([l,r]\) 完全包含,就要求任意 \(r-l+1\leq w(l,r)\),即 \(r-w(l,r)+1\leq l\)。对于每个 \(l\) 处理出 \(r-w(l,r)+1\) 的最大值 \(b_l\)。我们要求在有解前提下任意 \(b_l\leq l\)。删去第一个数后对后面的 \(b,i\) 均进行移位。考虑线段树维护 \(l-b_l\)。我们要求移位后全体数非负。注意到钦定第一个的影响是 \([1,b_x-1]\) 都减去 \(1\),那么线段树二分找出第一个 \(i=b_i\) 的位置 \(q\),我们要求 \(b_x\leq q\)。扫描线过程中开另一个线段树维护编号即可。时间复杂度 \(\mathcal O(n\log n)\)

联考 D4T2

考虑直接枚举 \(t\) 上的断点 \(i\),则可以在断点 \(i\) 处拼接的 \(x\) 满足 \(s[1:x]\)\(t[1:i]\) 的后缀,\(s[y:n]\)\(t[i+1:m]\) 的前缀。对 \(s\) 预处理正反串的 KMP,把 \(t\) 放在 \(s\) 正串上跑 KMP 到 \(t_i\) 时在 fail 树上的节点为 \(x'\),那么此处合法的 \(x\) 在 fail 树上 \(x'\) 到根的路径上,对于 \(y\) 同理。

考虑枚举 \(x\),合法的 \(y\) 就要求子树内所有 \(x'\) 在反串 fail 树上对应 \(y'\) 到根的链并上。链并即为 \(y'\) 和根节点构成的虚树,它的大小可以转换成 dfs 序相邻两点距离和再除以 \(2\)。所以按照反串 fail 树的 dfs 序建立线段树,在正串 fail 树上进行线段树合并即可。使用 \(\mathcal O(n\log n)-\mathcal O(1)\) 的 lca 可以做到 \(\mathcal O(n\log n)\) 时间复杂度。当然也可以在正串 fail 树执行 DSU on tree。这样是更好写的。

联考 D4T3

对 dag 的无出度点集进行容斥即可。也就是钦定 \(T\subseteq S,|T|>0\) 要求 \(T\) 中的点无出度,也就是说 \(T\) 是一个独立集。那么直接枚举可以做到 \(\mathcal O(3^n)\)。(半在线)子集卷积优化即可做到 \(\mathcal O(2^nn^2)\)

LOJ3537

  • 整体 dp,折半思想,bitset。

考虑简化一下每个 \(S_i\) 中两个 \(R\) 中间的部分。可以简化成一个函数 \(f:\lbrace0,1,\texttt{*}\rbrace\to \lbrace0,1,\texttt{*}\rbrace\) 表示在这个格子上的变换,总共有 \(4\) 种。全局而言相当于限制了合法的 \(p\) 是一段前缀。\(n\) 很小先考虑容斥钦定一个子集 \(S\subseteq\lbrace 1,2,\cdots,p\rbrace\) 表示要求有多少个 \(X,Y\)\(S\) 中任意一个起点出发的都是好的。 \(m\) 是没有什么用的,任意两个机器人间是独立的,对于一个子集的方案数 \(f(S)\) 只需要所有的机器人的方案数相乘。最终答案是 \(\sum (-1)^{|S|+1}f(S)\)

先考虑 \(\mathcal O(2^nnm)\) 就是每个格子有一些可行的值,全部相乘即可。更具体的,我们考虑将 \(f\) 刻画为:变 \(0/1\),取反,不变这 \(4\) 种情况。我们考虑每个格子被这四种情况的哪些操作覆盖了。显然变 \(0/1\) 互斥,取反与不变,互斥。否则:如果未被施加操作,\(X/Y\) 的对应有 \(3\) 种;被有且仅有一种操作施加,\(X/Y\) 的对应有 \(3\) 种;被两种互相不互斥的操作施加,\(X/Y\) 的对应有 \(2\) 种;否则只有 \(1\) 种。然后对于 \(4\) 种操作分开来处理,用一个 \(n\times m\)\(01\) 矩阵表示是否被施加该种操作,可以 bitset 优化,用 \(S\) 的 bitset 去推导出 \(S\cup\lbrace i\rbrace\) 的 bitset。时间复杂度 \(\mathcal O(\frac{2^nnm}{\omega})\)

注意到 \(n=32\) 并且感觉与 \(n=16\) 是强相关的。你考虑进行一个折半。考虑一个波特的移动涉及了 \(len_i\) 个格子。那么你考虑如果钦定的集合 \(S\) 中最大的元素 \(mx\) 过大的话那么我们要求 \(len\) 是小的。如果 \(mx\) 小的话 \(S\) 也不是很多,可以跑那个暴力。显然对于 \(mx\leq n/2\) 直接进行上文的暴力,复杂度是 \(\mathcal O(\frac{2^{n/2}nm}{w})\),可以接受。

问题在于求 \(mx>n/2\) 的部分。 此时一定满足 \(len_i\leq n-mx+1\),每个波特能影响的范围较少。那么你考虑某个位置 \(r\) 而言,他只与 \(S\) 是否包含前面 \(n/2\) 个元素有关,预处理一下贡献系数即可。总状态就是对于某个波特的 \(f_{i,S,0/1}\) 就是考虑到第 \(i\) 个元素,前 \(n/2\) 个元素的在钦定集合中的选取情况是 \(S\),你还要考虑再前面的点是否有被选取的点,这样这个滑动窗口移动的时候就可以判定被从尾部 pop 的这个元素是否是受限制的。考虑优化一下 \(m\) 的复杂度,你发现对于任意波特而言其转移形式全部相同,使用整体 dp 的方法优化,类似于上一部分,我们使用 bitset 记录一下 \(4\) 种情况的限制。这样整体转移的系数就可以快速求了。

总时间复杂度 \(\mathcal O(\frac{nm2^{n/2}}{\omega})\)

P10656

  • 单调性优化。

注意到 \(a,b\) 内部是互不相同的,那么存在各自全选的方案。如果 \(a,b\) 均有选择,那么一定满足 \(a,b\) 中的至少一个序列的区间和严格大于其总和的一半。如果两个都 \(\leq\) 一半,一定可以调整成全选某个。不妨设 \(a\) 的区间和严格大于其总和的一半,那么满足其首个前缀和 \(p\) 大于其总和一半,\(p\) 一定是必选的。

然后考虑 \(b\) 确定下来是哪个区间后可能会 ban 掉 \(a\) 中的一些点。然后被保留的 \(a\) 的区间就是 \(p\) 所在的极长连续段。对于 \(b\) 从左到右进行右端点 \(r\) 的扫描线。然后需要动态维护 \(res_l\) 表示 \(b\) 选取 \([l,r]\) 的答案。那么每次加进来一个 \(r\) 的时候考虑其与 \(p\) 的位置关系。分别是对每个 \(res_l\) 对应的 \(a\) 的区间 \(al,ar\)\(\text{chkmax}\) 或者 \(\text{chkmin}\) 操作。但这个题具有单调性,所以不需要用 beats,正常单调栈加线段树维护即可做到 \(\mathcal O(n\log n)\)

模拟赛 D9T1

考虑扫描线值域 \(lim\),将 \(\leq lim\) 的看成 \(1\)\(>lim\) 的看成 \(0\),那么一个 \((l,r,i)\) 合法的必要条件是恰好 \([l,i]\) 的前缀均为 \(1\)\([i+1,r]\) 的后缀均为 \(0\)。扫描线的时候将某个 \(0\) 转为 \(1\) 时关心一下 \(0\) 的极长连续段变化即可。就是若干矩形加,将询问离线下来二维数点即可。时间复杂度 \(\mathcal O(n\log n)\)

P4770

考虑对于 \(S\) 建立后缀自动机。由于你要求 \(T\) 自身选取出来的也是互不相同的,所以 \(T\) 也要建立后缀自动机。那么求出 \(P_i\) 表示 \(T[1:i]\)\(S\) 所有位置的 \(lcp\) 长度最大值。然后对于同一个 \(endpos\) 等价类统计答案的话,你需要求出该 \(endpos\) 集合中的最小值 \(firstpos\)。此时这个等价类贡献的答案是 \(\max(len_u-\max(len_u,P_{firstpos_u}),0)\)。对于 \(l=1,r=|S|\) 的跳 \(P\) 可以获得 \(68\) 分。具体而言,在匹配过程中维护当前在 \(S\) 上的状态 \(u\) 以及公共后缀长度 \(q\)。这个均摊复杂度 \(\mathcal O(T)\)。任意 \(l,r\) 的情况问题就在于优化求 \(P\) 序列的过程。然后你发现你需要查询的是一个节点的 \(endpos\) 集合是否与 \([l,r]\) 有交,动态开点线段树维护一下即可,一个节点的真实 \(endpos\) 就是线段树合并一下。时间复杂度 \(\mathcal O((n+\sum m)\log n)\)

LOJ3805

  • 数形结合,定义域值域互换,数据随机题。

考虑放到二维平面上刻画该问题,那么就是有若干点 \((i,a_i)\),我们要求对于任意横坐标 \([l,r]\) 的最小子矩形而言,就要求 \((l,a_l),(r,a_r)\) 这两个点至少一个在矩形的四个角上。先不管数据随机的限制,用记忆化搜索的思路我们思考如何生成一个合法序列,记当前还未填写的数是集合 \(S\),当前仍未填写的区间是 \([L,R]\),那么你每次是将 \(S_{\max},S_{\min}\) 的两者之一放到端点上,那么 \([L,R]\) 就缩减为 \([L,R-1]/[L+1,R]\),而 \(S\) 由于是删除最小或者最大值那么显然是连续的。也就是说对于大正方形你每次会删除一个 \(\texttt{L}\) 形。因此有一个 \(\mathcal O(n^3)\) 的状态设计就是,\(f_{l,r,x}\) 为当前为 \([l,r]\) 的区间时 \([x,x+r-l]\) 还未填写,这些所有序列与原序列的保留最大值。

注意到数据随机,猜测答案很大,事实上保留的数的级别是 \(\mathcal O(\sqrt n)\)。考虑“保留”是什么意思,对于 \(i\) 有四个方向的正方形其边长为 \(d\),那么就有 \((i,a_i)\) 往四个方向的正方形。我们考察被保留下来的 \(k\) 个点,那么就是要对于所有被保留的点,考虑一个严格单调的序列 \(d\) 以及方向 \(dir\) 来刻画其正方形。我们要求对于这 \(k\) 个正方形是两两严格包含的关系。

那么这样就很好做了。我们放到一个正方形上去分析,但之前我们宣称了答案的量级很小,原本是 \(f_{i,dir,j}\) 表示 \((i,a_i)\) 的第 \(dir\) 方向的正方形边长为 \(j\) 时最多包含多少个子正方形,显然其具有单调性,因此考虑定义域值域互换。可以更改为 \(g_{i,dir,j}\) 表示 \((i,a_i)\)\(dir\) 方向正方形,如果包含 \(\ge j\) 个子正方形,其要求最小的边长是 \(g_{i,dir,j}\)。考虑对于 \(j\) 维度进行扫描线,因为转移就是 \(g_{*,j}\)\(g_{*,j-1}\) 来转移。然后这就是一个二维平面的问题,可以用对角线拆成两个三角形,树状数组维护二维偏序做一下。时间复杂度 \(\mathcal O(n\sqrt n\log n)\)\(\mathcal O(\sqrt n)\) 的分析来自于随机序列的最长上升子序列期望长度。

只需要跑 \(8\) 次二维偏序就行了。优美的写法是每次旋转一下坐标系,但我不会。

联考 D5T2 / QOJ9278

考虑行列式定义式 \(\sum_p(-1)^{\sigma(p)}\prod a_{i,p_i}\),每个 \(a_{i,j}\) 的值为 \(\sum [i\in[l_q,r_q]\wedge j\in[l_q,r_q]]\)。那么考虑其组合意义:在 \(m\) 个正方形中选取 \(n\) 个行列各不重复的点,对答案计入 \((-1)^{\sigma(p)}\) 最后求和。我们要求每个正方形中被选取最多一个点,否则可以构造一个对称的排列消去 \(-1\) 的贡献。那么先考虑 \(m=n\),只需要判定答案是 \(0/1\) 之间的哪个数。强制钦定 \((1,1)\) 必选,进行高斯消元,那么就要求将所有 \(l=1\) 的操作中 \(r\) 的最小值,将 \([2,r]\times[2,r]\) 的矩阵消除成全 \(0\),然后再令 \((r+1,r+1)\)\(1\),以此类推。我们发现这就是所有 \((l,r+1)\) 连边后的生成树个数。然后注意到 \(m-n\leq 300\),跑 SNOI2020 生成树的广义串并联图方法缩到 \(n'\leq 600\) 的图。对这张图跑矩阵树定理即可。令 \(c=m-n\),时间复杂度为 \(\mathcal O(m\log n+c^3)\)

联考 D5T3

SAM 是一个 dag,很难做。考虑使用 SA 求。先考虑没有循环移位怎么做:将 \(n\) 个后缀拉出来排序,第 \(i\) 个后缀比第 \(i-1\) 个后缀多贡献 \(b_i=n-sa_i+1-\text{lcp}(sa_i,sa_{i-1})\)。对于 \(b\) 做前缀和找到第一个 \(\ge k\) 的位置 \(p\),左端点为 \(sa_p\),右端点推一下即可。拓展一下,循环移位我们将被移动的字符加入到最后,但是我们并不弹出最先的字符。令循环移位的操作数量是 \(q'\),我们会得到一个 \(n+q'\) 的串 \(s'\)。我们将 \(s'\) 进行后缀排序。一个错误的做法是,记当前 \(s\) 的区间是 \(s'[p:p+n-1]\),我们对于后缀数组保留后缀标号在此区间中的,并维护此时的 \(b\)。这个做法错误,是因为 \(suffix[x:n+q'],suffix[y:n+q']\) 的大小关系可能与当前的 \(suffix[x:p+n-1],suffix[y:y+n-1]\) 并不相同。我们发现这种错误发生当且仅当此时一个后缀现在是另一个后缀的前缀,然后在后面有一个不同的位置将它们的大小关系翻转了。

我们不保留被包含的后缀,只维护当前不被包含于其他后缀的后缀,维护当前的 \(b\),在这个上面做前缀和二分就是正确的。因为这已经表示出了所有的本质不同子串,并且大小关系正确。

那么考虑计算 \(f_i\) 表示在移位版本超过 \(f_i\)\(suffix_i\) 不作为当前 \(suffix\) 中其他串的前缀出现(容易证明 \(f\) 显然是唯 一且存在的,因为串越长越难以在其他串出现)。\(f\) 的求法较为复杂,分讨一下 \(i,j\) 的关系。求得 \(f\) 后进行扫描线,动态维护全局被保留的点的 \(b\)\(n\) 作为参数,然后线段树二分起点即可。时间复杂度 \(\mathcal O(n\log n)\)

std 11kb,这题狗都不写,代码摆了。

模拟赛 R6T2

先考虑 \(m=n-3\) 即给出了一个三角剖分怎么做。两两之间贡献全部计算的问题可以考虑进行分治。本题中一个分治对象是多边形 \(G\)。可以由点集 \(V\) 以及边集 \(E\) 来唯一描述。那么所谓的分治中心就是,一条边 \(e\) 满足这个多边形沿着 \(e\) 切开后形成的两个多边形 \(G_1,G_2\) 满足两者尽量均衡。注意 \(e=(u,v)\) 的端点在 \(G_1,G_2\) 均存在。递归终止当且仅当 \(|V|=|E|=3\),此时贡献容易计算。否则我们找出 \(\max(|V_1|,|V_2|)\) 的分治中心切开后,任意 \(i\in V_1\)\(j\in V_2\) 的路径必然经过 \(u,v\) 其中至少一个点。由于是无向图,所以放在 \(u/v\) 上统计。求出 \(u\) 到任意一个 \(V\) 中点的最短路 \(a_i\)\(v\) 同理有 \(b_i\),可以跑 \(\text{Dijkstra}\) 算法。那么 \(dis(i,j)=\min(a_i+a_j,b_i+b_j)\)。此时 \(a_i+a_j\leq b_i+b_j\) 当且仅当 \(a_i-b_i\leq b_j-a_j\)。枚举 \(i\) 然后对于右边的东西排序算一下后缀 \(a\) 的和前缀 \(b\) 的和即可快速统计所有 \(dis(i,j\in V_2)\) 的贡献和。分治深度最多 \(\log_{3/2}n=\mathcal O(\log n)\),每层都是带 \(\log\) 的。因此时间复杂度 \(\mathcal O(n\log^2 n)\)

提一下怎么补全成三角剖分。考虑不断删除边界上的三角形的外顶点 \(u\),这要求 \(u\) 的度数恰好为 \(2\) 也就是说连边均为当前多边形边界的边。对于当前多边形边界可以用链表维护。然后考虑无法删除但仍未形成三角剖分时的情况,我们任取一个度数为 \(2\) 的点 \(u\),将其连接的 \(v,w\) 添加一条 \((v,w)\) 的边,边权为 \(+\infty\),此时 \(v,w\) 即为链表上 \(u\) 的前驱后继。 用一个队列维护待删的点,另外用一个 set 维护 \(2\) 度点。每次删除一个点修改链表以及刷新连接的点是否可以加入队列,以及二度点情况即可。

模拟赛 R6T3

我们希望对于每个 \(1\le m\le k\) 计算最大值 \(\le m\) 的方案数,依此可以容易计算答案。

只需要求 \([x^k]S_m^n(x)\) 其中 \(S_m(x)=\sum\limits_{i\le m}\dfrac{x^i}{i!}\)

\(S_m(x)\)\(e^x\) 展开式的截断,考虑 \((S_m(x))'=S_m(x)-\dfrac{x^m}{m!}\),则 \((S_m^n)'=nS_m^{n-1}(S_m-\dfrac{x^m}{m!})=nS_m^n-nS_m^{n-1}\dfrac{x^m}{m!}\),则固定 \(m\),可以在 \(\mathcal O(nk)\) 的时间内递推出所有 \(S_m^i,0\le i\le n\),总复杂度 \(\mathcal O(nk^2)\)

发现 \(S_m^n\) 需要求到第 \(k\) 项,而 \(S_m^{n-1}\) 只需要求到第 \(k-m-1\) 项,并且 \(mn\le k\) 的情况无贡献,则对于每个 \(m\),时间复杂度变为 \(\frac{k^2}{m}\),总复杂度 \(k^2(\log k-\log (\frac{k}{n}))=\mathcal O(k^2\log n)\)

若知道了各个 \(S_m^i\),那么 \([x^k]S_{m+1}^n\) 也是容易计算的。考虑定期重构,设阈值 \(B\),先预处理出所有 \(B\mid m,1\le i\le n\)\(S_m^i\),这里的复杂度为 \(\mathcal O(\dfrac{nk^2}{B})\)

对于任意 \(m=Bl+r\),展开 \(S_m^n=(S_{Bl}+(S_m-S_{Bl}))^n=\sum\limits_{i}\binom{n}{i}S_{Bl}^{n-i}(S_m-S_{Bl})^i\),后者有 \(ir\) 项,并且可以类似上文做法递推出所有值,而前者均已经算过,这部分复杂度为 \(\mathcal O(kn^2B)\),平衡得到 \(\mathcal O(n^{1.5}k^{1.5})\)

进一步的,同上文分析,对于 \(S_{Bl}^{n-i}\),只需计算 \(k-(Bl+1)i\) 项,而由于 \(S_m-S_{Bl}\) 最低项也为 \(Bl+1\),这样的数量足够支持后面的计算,则计算单个 \(m\) 的复杂度为 \(\mathcal O(d(\frac{k}{m})^2)\),其中 \(d\) 是与上一次重构的距离,在 \(m\) 处重构的复杂度为 \(\mathcal O(\frac{k^2}{m})\)

设在 \(m\) 处重构的概率为 \(p\),可以认为 \(d=\frac{1}{p}\),则可以认为在单个 \(m\) 的复杂度为 \(\mathcal O(p^{-1}(\frac{k}{m})^2+p\frac{k^2}{m})\),取 \(p=m^{-0.5}\) 得到 \(\mathcal O(k^2m^{-1.5})\),对 \(m\)\(\frac{k}{n}\)\(k\) 求和可得 \(\mathcal O(k^2(\frac{k}{n})^{-0.5})=\mathcal O(k^{1.5}n^{0.5})\),可以通过本题。

联考 D6T1

考虑暴力怎么做,直接 \(f_{i,u}\) 表示 \(i\) 时刻 \(u\) 节点期望人数。那么对于大多数的 \(T-m\) 个时刻都是乘上一个转移矩阵 \(M\),对于有人员加入的时刻的转移矩阵是特殊的。注意到本题只需要做到求出所有 \(f_{i,n}\) 的值。那么对于 \(\mathcal O(m)\) 个平凡的段而言,我们考虑用较低的复杂度求出所有这些段的 \(f_{i,n}\)。而对于 \(m\) 个特殊时刻而言我们要知道对于这个位置的 dp 向量,即支持 \(F_{x,y}\) 自增,然后考虑变化量。可以考虑定期重构整个矩阵,我们对于每 \(B\) 个位置重新一遍真实的 \(f\),对于中间这些跳过的位置我们只需要求一个位置的值,预处理贡献系数即可,所以这个求单项而言这个是 \(\mathcal O(n)\) 的。求出 \(M\)\(1\sim B\) 次方的时间复杂度是 \(\mathcal O(n^3B)\),定期重构总复杂度 \(\mathcal O(n^2T/B)\),取 \(B=\sqrt{\frac{T}{n}}\) 进行平衡。时间复杂度 \(\mathcal O(nT+mn^2+n^{2.5}T^{0.5})\)

联考 D6T2

首先将条件转化为 \(a_{i+1}-a_i=a_{i}-a_{i-1}\),也就是说告诉你差分数组 \(c_i=a_{i}-a_{i-1}\) 的两个相邻位置相等。那么我们考虑将原序列用来生成若干连续段 \([l,r]\)。满足任意 \(i\in(l+1,r]\)\(c_i=c_{i-1}\)。注意边界的点应该同时出现在两个连续段,分别作为终点与起点。显然如果一个连续段内已知至少两个 \(a\) 那么就是可以直接得知的。否则考虑分为三种:在 \(l/r\) 上是唯一一个已知的 \(a\);在 \((l,r)\) 中间是唯一一个已知的 \(a\);没有已知的 \(a\)。显然对于中间有 \(a\) 的情况,其合法性可以用来传递,你可以合并两端的段;手玩一下发现对于第一种情况而言是比较困难有解的,事实上可以直接合并 \(2/4\) 情况。用一个 set 维护 \(1/3/4\) 情况的连续段,以及所有情况的连续段。树状数组支持查询区间内 \(a\) 已知点的数量。时间复杂度 \(\mathcal O(n\log n)\)

联考 D6T3

\(\mathcal O(n^3)\) 把 std 薄纱了,不评价。

QOJ9904

考虑直接使用 kruskal 算法,对 \(a\) 进行排序,这要求我们对 \(k=u+(k-u)\) 的所有边 \((u,v)\) 尽量连边。那么我们需要支持插入该边权所有边以及查询这类边会有多少条在边在 MST 中。然后可以考虑经典套路,对于每一次拓展二分找到对于当前 \(k\) 最小的一对不在同一个连通块中的边。那么就需要判定 \(V=[l,r]\cup[k-r,k-l]\) 是否满足每个对应的边都不是同一个连通块。我们考虑对于同一种连通块的颜色,给这个点赋上这个颜色对应的权值,这个权值是你给出的两两不同的任意实数,可以用 \([0,2^{64}-1]\) 中随机正整数代替,那么我们要求找出首个不是同个连通块的,也就是说两者权值不同。我们要求极长保留的,要求 \(i,k-i\) 的颜色相同,这相当于判定是否构成回文串。线段树维护一下正反串的哈希值,然后对于每次加边即合并连通块,使用启发式合并修改小集合中每个点的颜色为大集合的颜色。时间复杂度 \(\mathcal O(n\log^2n)\)

QOJ9905

注意到原树合法当且仅当存在一个点权递降的 bfs 序。注意到总和 \(\leq 10^{15}\),有解时树高不会很大,大概是 \(h=\mathcal O(\log n)\)。取 \(h=75\) 然后暴力跳祖先更新即可。对于构造就是考虑类似于毛毛虫的东西,从底往上填写即可。

LOJ6759

考虑最小割转最大流。那么对于一个点拆入点 \(in_u,out_u\) 连边 \(in_u\to out_u\),容量为 \(1\)。对于原图存在的点与点之间的边我们保留,并设容量为 \(+\infty\),因为我们只能选择点割掉。然后添加一个超级源点 \(S'\) 向所有 \(S\) 中的 \(in_i\) 连容量 \(+\infty\) 的边,对于超级汇点 \(T'\) 同理。此时考虑最大流的意义:我们要最大化选取 \(S'\)\(T'\)\(k\) 条有向路径 \(P\),满足任意两条不同的 \(P_i,P_j\) 没有公共的容量为 \(1\) 的边。 这仍然不好考虑,我们将容量为 \(1\) 的边 \((in_u,out_u)\) 视作重构图 \(G'\) 上的一个点 \(u'\)。我们对于路径 \(a\to b\to c\to d\),满足 \(w(a,b)=w(c,d)=1,w(b,c)=+\infty\) 而言,建立 \((a,b)\to (c,d)\) 的有向边。此时就成功的将原图刻画到了重构图 \(G'\)。然后你发现这个 \(G'\) 就是原图。

现在我们要最大化 \(k\) 使得存在 \(k\) 条不交路径组。可以考虑 LGV 引理,并使用 PA2021 某个题的套路,你发现权值中 \((-1)^{\sigma (p)}\) 很烦,但是本题是判定【是否存在】,不需要数数。所以可以考虑选定一个大质数 \(P\)(本题取 \(P=998244353\) 即可),然后对每条边赋一个 \([0,P-1]\) 的随机边权。直接重新称呼一条路径的权值是 \(\prod w_i\)。无解时,求出来的行列式值一定 \(=0\),有解极大概率 \(\ne 0\)。首先跑一遍 \(e_{u,v}\) 表示起点为 \(u\),终点为 \(v\) 的所有路径的权值(即随机边权的乘积 \(\bmod \text{ }p\))的和,这是 LGV 引理需要的。对于一个 \(x\),就相当于可以选出来 \(x\) 个起点,\(x\) 个终点,拉出来这些可以搞出来一个行列式 \(\ne 0\)\(x\times x\) 矩阵,也就是矩阵的秩为 \(\ge x\) 的。最大化当然就是这个矩阵的秩 \(k\) 本身。

回到原题,我们需要计算给定起点集合 \(S\) 以及终点集合 \(T\) 每对点的路径权值和。对于单点修改的维护,使用线段树来维护矩阵乘法即可。时间复杂度 \(\mathcal O((n+q\log n)k^3)\)

QOJ9907

考虑 \(m=0\) 怎么做:我们先将同色位置拉出来做匹配,在最大化同色匹配数的前提下,我们要求失配的 \(0\) 尽量靠左,失配的 \(1\) 尽量靠右,这样这些在最后异色匹配产生贡献的可能性就会尽可能大。同色可以贡献的匹配数就是 \(1\) 的总数减去适配的 \(1\)。令 \(0\) 代表权值 \(+1\)\(1\) 代表权值 \(-1\),我们发现失配的 \(1\) 就是做前缀和后的严格前缀最小值位置。那么对于 \(0\) 类似地考虑严格后缀最小值位置即可。然后对于失配的位置再单独拉出来我们统计有多少匹配即可。对于修改而言,只有 \(\mathcal O(1)\) 个位置的失配情况变化,考虑怎么找,转为 \(1,-1\) 折线图后进行线段树二分即可。一个比较妙的写法是对于撤销贡献时添加一个相反括号种类,这样对折线的影响就正确了。

QOJ7989

  • 待定的值可以设为 dp 状态。

先考虑判定一个方案是否会终止。手玩发现如果存在同构于 \(\begin{bmatrix} a & a\\ b & c \end{bmatrix}\)\(2\times 2\) 子矩形,那么这个子矩形会无限循环变换。如果最后有一个大循环,那么一定能找到一个小循环形如上面的矩形。你发现这个是事实上就是充分必要的。此时第一问考虑做轮廓线 dp,\(f_{i,j,S}\) 表示填写前 \(i-1\) 列以及第 \(i\) 列前 \(j\) 行的合法方案数,并且描述了第 \(i\) 列前 \(j\) 个以及第 \(i-1\)\(j\sim n\) 的具体状态。可以 \(\mathcal O(1)\) 转移。时间复杂度 \(\mathcal O(3^{n+1}nm)\),可以通过第一问。更暴力的 \(\mathcal O(m6^n)\) 也可以轻松过第一问,这是因为有效的转移数量只有 \(\mathcal O(6^n)\)

\(3\) 意义下是不好分析的,考虑给每个位置设计权值 \(b_{i,j}\equiv a_{i,j}\pmod 3\)。并且我们要求两两边相邻的 \(b\) 的差绝对值 \(\leq 1\)。也就是说 \(a,b\) 差分的变化是完全相同的。我们考虑如果模 \(3\) 意义下矩阵相邻两个点 \(a_x=a_y+1\),那么就要求 \(b_x=b_y+1\)。然后发现每次操作事实上就是在与周围边相邻的点的 \(b\) 权值做 \(\text{chkmin}\)。答案也很好刻画:最后一次 \(b_{1,1}\) 不再改变的时刻。 显然最后所有的 \(b\) 都会变成初始状态中 \(b\) 的全局最小值, \(b_{1,1}\) 最后一次改变时间就是距离 \(b_{1,1}\) 最近的全局最小值,距离定义为曼哈顿距离。给定矩阵 \(a\) 确定矩阵 \(b\) 是简单的,令 \(b_{1,1}=a_{1,1}\),然后从左往右从上往下递推 \(b\) 即可。

考虑在一开始就确定 \(b\) 的全局 \(\min\) 值为 \(P\)。注意 \(b\) 的取值是 \(\mathcal O(n+m)\) 的,但由于我们关心的是 \(P\) 的位置以及 \(b\) 的传递关系,我们只需要在状态中记录相对关系而非绝对数值。必然有的两个状态是 \(f_{i,S}\) 表示前 \(i\) 列而第 \(i\) 列状态是 \(S\),然后考虑记录 \(j=b_{1,i}-P\)。此时要考虑曼哈顿距离,而曼哈顿距离 \(d\) 描述的是一条斜线,此时我们已知的变量只有 \(i\),直接记录 \(d\) 是不好做的。转移的时候我们希望判定是否可以在新的一列成为全局最小值 \(P\)。所以可以记录 \(\max(d-i,0)=k\)。因此状态就是 \(f_{i,j,k,S}\) 以及一个 \(g\) 分别表示方案数以及贡献和。时间复杂度 \(\mathcal O(6^n(n+m)nm)\)。转移的思想是 \(g\) 是一个累加量,对于每个方案找最近的最小值计入答案即可。

花花的 \(\mathcal O(3^nn^2m^2)\) 完全不会。

联考 D7T2

注意到 \(p\) 的给出是一种长链剖分的形式。考虑一个 \(u\to v\) 的路径,一定是先走到 \(\text{lca}(u,v)\) 的某个祖先 \(k\),然后再从 \(k\) 一直走 \(p\) 下去,此时我们要求 \(v\)\(k\) 所在长链上的点。代价是确定的一个一次函数 \(y=x+t\),也并不需要考虑 \(S\) 的限制。注意到 \(2\leq b_k\) 的限制非常奇怪,有一个关于路径形式的结论是,如果要往上走,一定是先往儿子走一步再跳某个 \(b_i\) 级祖先,也就是说我们的操作可以转化为,令所有 \(b\) 减去 \(1\) 然后可以从一个非叶子节点起跳到某个 \(b_i\) 级祖先上。对于所有情况,注意到 \(\text{lca}\) 是重要的,我们的操作应该是 \(dis(u,lca)\) 加上某些常数,而枚举 \(\text{lca}\) 的步骤考虑继承重子树枚举轻子树。状态是长度为 \(d\) 的链,跳到恰好 \(i\) 级父亲的最小代价 \(f_{d,i}\),用贪心的思想,那么分为以下若干情况。

  • \(u\)\(lca\) 本身,\(v\) 为重子树的链上点。可以简单求和。
  • \(u\) 为重子树的点,\(v\) 为当前正在枚举的 \(lca\)。可以拆贡献,在 \(u\) 处计算贡献。由于一个点到根路径只有 \(\mathcal O(\sqrt n)\) 条轻边,所以可以对所有拆成的重链一起处理。
  • \(u\) 为轻子树的点,需要先走到 \(lca\) 处,而 \(v\) 为重子树的点,后者可以拆贡献简单计算。因此问题在于刻画出所有 \(dis(u,lca)\)

先考虑 \(f\) 的转移,并不能直接按照某种顺序计算。分为两种情况:跳祖先和从祖先下来。直接抽象成图上最短路从 \(f_0=0\)\(\text{Dijkstra}\) 算法求出所有的 \(f\) 即可。我们可以对于所有长链都去计算所有的 \(f\),时间复杂度 \(\mathcal O(nm+n\log n)\)。然后对于一个 \(dis(u,lca)\),我们宣称直接放在 \(f_{top_{lca},u}\) 就是正确的。你考虑为什么切换链我们直接将跳的过程放到最终 \(lca\)\(top_{lca}\) 是对的,这是因为链长都是相等的,一个 \(top_{lca}\) 上的操作序列唯一对应一个 \(u\to lca\) 的操作序列,因此是对的,这样对于 \(d\) 来计算的复杂度以及信息的刻画就正确了。子树合并需要合并一下距离 \(u\)\(i\) 的个数。

时间复杂度 \(\mathcal O(n\log n+mn+n\sqrt n)\)

P9265

这不是我们 CF1270H 的建图吗。首先每个连通块一定是一段极长区间 \([l,r]\),其次考虑分界点是什么,要求前缀 \(\min\) 小于后缀 \(\max\)。对于序列就可以先进行初步的划分,每个区间内都是两两可达的。对于连通块我们分开来处理。由于边权都是 \(1\) 所以考虑进行 bfs。我们将最短路之和转化为对于所有 \(d\) 计算有多少 \(dis(i,j)\ge d\),对于这个对数求和即可。

你考虑将这个事情放到一个二维平面上刻画。注意到 \(d=1,2\) 是平凡的,考虑刻画 \(d=3\):我们希望对于一个 \(i\),第一步走 \(j<i\)\(j\) 最小且 \(p_j>p_i\) 的点 \(j\),这是因为 \(2\) 步可以到达的一定是 \(p_k<p_i\),且 \(k<i\) 的,那么选择 \(j\) 最小的是优的。右侧同理。那么我们找出第一步走的点 \(pre,nxt\),此时至少 \(3\) 步的点就满足:\(k<pre_i,p_k<p_{nxt_i}\) 以及右侧的部分。那么就是对于未覆盖的左上角和右下角进行一缩减。考虑拓展到 \(d\) 任意的情况。我们发现就是对于上一个矩形的覆盖,再添加当前的 \(pre,nxt\) 的限制。对于 \(pre,nxt\) 考虑用一个数对 \((x,y)\) 来刻画,每次执行 \(x=pre_y,y=nxt_x\),然后统计一个矩形右上角和左下角的点数。

那么考虑对所有区间对 \((x,y)\) 进行刻画,可以建立一棵内向树。然后这个点数是 \(\mathcal O(n\sqrt n)\) 的。因为每一步要么 \(x+y\) 减少 \(\sqrt n\),要么 \(|x-nxt|\) 减少 \(\sqrt n\)。那么要查询某个点到根的权值和。而每个点的点权是矩形数点,可以根号 \(\log\) 做。然后一个祖先递降链上的 \(x\) 是具有单调性的。那么如果建出来了树的话按照 \(x\) 进行扫描线,此时父亲一定先扫到,只需要支持 \(\mathcal O(n)\) 次修改 \(\mathcal O(n\sqrt n)\) 次查询。建树可以直接哈希表 bfs;另一种方法是利用 \(x,y\) 各自的单调性,从右到左扫每个位置作为左端点的 \((x,y)\),这样新加入的时候只需要判断是否重复。时间复杂度 \(\mathcal O(n\sqrt n)\)

CF2057E2

考虑进行二分答案 \(mid\),将边权 \(\leq mid\) 的设置为 \(0\),否则设置为 \(1\)。我们要求 \(u\to v\) 最短路 \(<k\)。我们考虑在某种边权下的图可以将所有点缩成若干大点,大点内部是 \(0\) 权边表示这是一个等价类。然而等价类之间的边必须是 \(1\)。每次就是缩 \(u,v\) 的等价类。考虑动态维护 \(f_{i,u,v}\) 表示第 \(i\) 个版本 \(u\to v\) 的最短路,那么每次有效的更新就是对于两个不同等价类的合并,直接进行 \(\mathcal O(n^2)\) 的更新即可。有效的更新显然只有 \(n-1\) 次。然后询问就是直接二分,时间复杂度 \(\mathcal O(n^3\alpha(n)+q\log n)\)

联考 D8T1

注意到我们容易确定 \(A/B\) 哪个队是胜利的。那么对于输的队而言其必然消耗掉自己全部的牌。不妨设 \(A\) 队所有人都输光了自己手中的牌,那么我们可以将一次打牌设置为,\(A\) 出一张牌,\(B\) 找到最近的牌进行匹配。这样一组 \(AB\) 是一次统计。如果一开始是 \(B\) 打就微调一次。那么我们希望对于所有 \(B\) 中的成员算出它匹配了有多少 \(A\) 的牌。那么对于赢的队而言,考虑在环上扫一遍,我们并不关心具体是哪个 \(A\) 与其进行了匹配。直接维护当前 \(cnt\) 表示待匹配的 \(A\) 以及剩余的 \(A\) 的数量 \(s\) 即可。时间复杂度 \(\mathcal O(n)\)

联考 D8T3

考虑子任务 \(4\),相当于从右往左,每次加入一列,求最小生成树。假如我们要给一个图加入一条边 \((x,y,z)\),如果 \(x,y\) 不连通,则直接连,否则需要找出最小生成树中 \((x,y)\) 路径上的边权最大的边 \((u,v,w)\),若 \(w>z\) 则将 \((u,v,w)\) 替换为 \((x,y,z)\),否则不操作。由于不相邻的列之间没有连边,我们可以只保留最左边的列上每个点在最小生成树上形成的虚树,虚树上的边边权为原树路径上的最大值,其余的边一定不会被删掉。我们每一轮只记录关键边,递推时拿关键边和新边跑 kruskal。非关键边的边不可能被删,只需记录总和。这样每次合并只用求点边均 \(\mathcal O(n)\) 级别的最小生成树。那么正解就只需对前后缀都求一遍,然后合并起来。对每个前后缀预先按边权排序后即可做到 \(\mathcal O(nm\log n+nq\alpha(nm))\)

P7564

顺着做就没了,没意思。

注意到保镖一直移动是一定不劣的,这是因为保镖与人相距 \(1\) 是可以与其进行相遇然后共同行走 \(1/2\) 个单位距离然后获取 \(c_i/2\) 的回报。那么考虑直观地刻画这个过程,放到二维平面的 \(x-t\) 图上进行分析,保镖是斜率为 \(-1/1\) 的折线段,而人是一个确定的斜率为 \(-1/1\) 的线段。那么保镖的收入就是看其路径与所有人的线段的交集。其实这样做还是不明显的,因此考虑对坐标系旋转 \(45\) 度,此时每个人就是一个与 \(x\) 轴平行的线段,而保镖可以是垂直向上走的。然后回顾一下 \(c_i/2\) 的事情,可以修改一下单位长度的定义,现在的单位长度是原来的 \(\frac{\sqrt{2}}{2}\)。此时关键的点就是所有 \(x/t\) 的点,注意到 \(n\) 是小的,因此对于 \(x/t\) 分别进行离散化,找出 \(n^2\) 个关键点。显然折线的转向只会考虑在关键点上。

注意到一个保镖的工作时刻是没有上限的,因此走到一个格点的部分形成一个子问题。因此可以做一个 \(\mathcal O(n^2)\) 的 dp 状态为 \(f_{i,j}\) 表示从格点 \((i,j)\) 作为起点往右上走的最大收益,这是 \(2D-0D\) 的因此可以接受。问题在于对于任意查询找到其到某个格点之前的收益,那么路径形式一定是横平竖直地走一段到某个线上,然后再沿方向走到格点,此时加上 \(f\) 的贡献。那么考虑有两种方向,做法是对称的。以向右走到某条线然后垂直向上走为例,就形如最大化 \(y=kx+b\)。离线扫横轴然后李超树即可。时间复杂度 \(\mathcal O(n^2+q\log n)\)

posted @   nullptr_qwq  阅读(59)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示