CFR#745 Partial Editorial

我认真地打了本场 CF,将力所能及的题目进行了订正。下面是所有做出的题目的题解。
Contest link

D2A

求有多少个长为 \(2n\) 的排列 \(p\) 满足

  • 满足 \(p_i<p_{i+1}(1\le i<2n)\)\(i\) 的个数 \(\ge n\)

极易发现排列的对称性,即如果排列 \(p_1p_2...p_n\) 满足条件,则 \(p_np_{n-1}...p_1\) 必然不满足。因此答案为 \((2n)!/2=3\times4\times...\times n\)
Time Complexity(单组数据): \(O(n)\)

D2B

判断是否可能造出一张无向连通简单图 \(G=(V,E)\),使 \(|V|=n,|E|=m\),且图的最远点对距离 \(<k-1\)

  • 须有 \(k\ge 3\)(但可以特判 \(k=2,n=1,m=0\) 的情形)
  • \(k>3\)
    • 图要连通,因此须有 \(m\ge n-1\)
    • 考虑构造菊花图,则但凡满足上一点就可以使最远点对距离 \(\le 2\)。因此,\(k>3\) 直接可行
  • \(k=3\) 的情况。则必须是完全图。则须有 \(m\ge n(n-1)/2\)

D2C

给定 01 矩阵 \(a\) 。你可以进行如下操作

  • 选择一个位置反色(1 变 0,0 变 1)

问使得 \(a\) 满足下述条件的最少操作数

  • \(\exists\) 大小为 \(a×b\) 的矩形 \(M\) 满足以下条件:
    • \(a≥5\)\(b≥4\)
    • 对于所有 \(1<x<a\),块 \(M_{x,1}\)\(M_{x,b}\) 为 1。
    • 对于所有 \(1<x<b\),块 \(M_{1,x}\)\(M_{a,x}\) 是黑曜石块。
    • 对于所有 \(1<x<a,1<y<b\),块 \(M_{x,y}\) 是一个空块。
    • \(M_{1,1},M_{1,b},M_{a,1},M_{a,b}\) 可以是任何类型。

需要一定的思维。

考虑枚举矩形的上下界(并且定住它)。考虑以类似双指针的方式移动左右边界。

首先枚举矩形的右边界。当一个以当前右边界为右边界、4为宽的矩形的代价<以当前右边界为右边界、当前左边界为左边界的矩形的代价时,将左边界移动到新矩形对应的左边界位置(即右边界-3处)。

关于算代价:用一个变量 \(cnt\) 记录每个矩形 不计右边界这一条线 需要的代价,对每一个右边界的位置,再临时用 \(cnt\) 加上右边界所需的代价来更新答案。每向右移动一次右边界,只需要在 \(cnt\) 上更新上下边界新增的总计2个位置的代价。每移动一次左边界,重新利用二维前缀和算代价。

关于预处理:预处理出二维前缀和数组就够用了。

【参考代码】CF Submission

D2E(stressed)

前置知识:根号平衡思想。

算法概述:对于一些特殊的操作 \(f(a)\)\(a\) 代表操作参数),分 \(a\)\(\sqrt n\) 的大小关系,一半采用暴力,一半采用特殊手段,从而使两种复杂度都为 \(O(n\sqrt n)\),总复杂度 \(O(n\sqrt n)\)。分块思想即从此衍生而来。

一共 \(n\) 辆火车,每辆有两个参数 \(x_i,y_i\)

一共有 \(m\) 天,每天会有一个事件:一辆火车 \(k_i\) 开始使用,或一辆火车 \(k_i\) 停止使用。

一辆火车 \(k\) 在使用过程中会先工作 \(x_k\) 天,再维修 \(y_k\) 天,再工作 \(x_k\) 天,如此往复,直至它被停止使用。停止使用的那一天被视作没有被使用。

对于 \(1..m\) 中每一天,求这一天有多少火车在维修。

观察到火车的使用具有周期性和区间性,分类讨论:

  • \(x+y>\sqrt m\)
    • 不会超过 \(\sqrt m\) 个“工作、维修”周期,可以直接在差分序列上对维修区间的始末打标记
  • \(x+y\le \sqrt m\)
    • 对于火车 \(k\),什么样的天 \(t\) 是维修日呢?\((t-s_k)\bmod (x_k+y_k)\ge x_k\) 时(\(s_k\) 表示火车 \(k\) 的开始使用日期)
    • 实时维护一个大小为 \(\sqrt m\) 的数组 \(f\)\(f_{p,q}\) 表示第 \(t≡q(\bmod p)\) 天有多少辆 \(x+y=p\) 的火车在维修。
    • 研究第一排的式子,设 \(v=(t-s_k)\bmod (x_k+y_k)\ge x_k\),则 \(v≡t-s_k\),则 \(t≡v+s_k\)
    • 于是对于每一次加入的火车,将 $f_{(v+s_k)\bmod p}++,v\in[x_k,x_k+y_k) \(;在每一次结束时\)--$;在每一天 \(1\le t\le m\) 统计 \(\sum _{i\le \sqrt m}f_{i,t\bmod i}\) 为这一天的答案。

【参考代码】CF Submission

D2F(Stressed)

前置知识:笛卡尔树(分治),树形 DP

算法概述:

  • 对于一个数列 \(a\),找出它的最小值 \(a_A\),将数列分成 \([1,A),a_A,(A,n]\) 三个部分。
  • 找出 \(a[1,A)\) 的最小值 \(a_B\),找出 \(a(A,n]\) 的最小值 \(a_C\),将 \(A\) 作为二叉树的根,\(B,C\) 作为它的两个儿子。
  • \(B\)\(C\) 的区间往复操作,最终将序列转为一棵树,且这棵树满足两个性质:
    1. 是一个小根堆
    2. 中序遍历是 \(1,2,...,n\)

讲解本题分为三个部分:建树、公式变形、DP。

对题目中的序列建立笛卡尔树。

观察题目公式,\(\iff \sum_{i=1}^m\sum_{j=i+1}^ma_{b_i}+a_{b_j}-2f(b_i,b_j)\)。而树上两点距离公式为 \(g_u+g_v-2g(LCA(u,v))\),是不是很像?

我们发现,只要把笛卡尔树上两点 \(i,j\)\(i\) 的深度大于 \(j\)) 之间的边权设为 \(a_i-a_j\),上式的右半部分就是 \(b_i,b_j\) 的树上距离。而左右端点下标的 \(LCA\) 就是区间的最小值下标。

题目转为:在树上求 \(m\) 个点,使两两距离之和最大。

考虑树 DP。设 \(f_{u,k}\) 表示当前考虑到节点 \(u\),在 \(u\) 的子树中选 \(k\) 个点的最大两两距离和。

我们很容易想到这个转移式(\(l,r\) 是二叉树中 \(u\) 的左右儿子) \(f_{u,i+j}=f_{l,i}+f_{r,j}+\forall p\in l\text{'s subtree},q\in r\text{'s subtree},a_p+a_q-2a_u\)

也就是说,我们只是在求距离和的最大值,确切地说,单一子树内距离和的最大值。

然而这个式子是错误的。为什么?因为我们没有完整地统计所有一个节点产生的贡献。我们知道,一个节点但凡被选,就会产生 \((m-1)\) 条路径以它为起点,它会立刻对答案产生 \((m-1)\times a_*\) 的贡献。因此我们的 DP 式是

\[f[p][i+j]=\max(f[p][i+j],f[l][i]+f[r][j]-2\times i\times j\times a[p])\\ f[p][i+j+1]=\max(f[p][i+j+1],f[l][i]+f[r][j]-2\times i\times j\times a[p]-2\times (i+j)\times a[p]+(m-1)\times a[p]) \]

CF Submission

这一题相当有难度,这个 DP 式也不好想,尤其不容易直接将带 \(m\) 的贡献直接统计到 \(f\) 中。但只有这样才是不会漏掉任何一个贡献并从而让每一次决策都具有全局性。

另一种建树方法:submission

复杂度分析:对于单一子树,其复杂度为 \(O(siz(l)siz(r))\) 的,又由基本不等式知 \(O(siz(l)siz(r))\le O(siz(l)+siz(r))=O(siz(u))\),总复杂度 \(\sum_{1\le u\le n}O(siz(u))=O(n^2)\)

posted @ 2021-10-04 19:31  pengyule  阅读(11)  评论(0编辑  收藏  举报