2024.3 做题记录

2024.3 做题记录

注:只摘录具有较高思考价值以及较高思维含量的题目(说白了就是颓出来的题)。

[JSOI2008] 火星人

我们只考虑查询操作,方法很多,例如 KMP、哈希、SA。

此时考虑修改,由于 KMP、SA 不好维护修改后的数组,因此考虑哈希。

我们利用二分答案的方式求出长度,利用哈希检查即可。

现在考虑 2,3 操作,由于有插入,我们考虑用平衡树维护哈希值。

显然如果这样考虑,我们是按下标排序。

接下来考虑如何求出哈希值,也就是怎么写 pushup。有下列式子:

\[hs_p=hs_{lp}\times base^{sz_{rp}+1}+val_p\times base^{sz_{rp}}+hs_{rp} \]

这样我们利用平衡树维护一下就行了。

  • 注意不保证 \(x<y\)
  • 注意 \(x\) 可能是叶子结点,因此修改时需要同时修改 \(val\)\(hs\)

[TJOI2013] 最长上升子序列

首先有这样一条显然的性质:

新插入的数必然比前面的数要大。

因此根据朴素的转移方程 \(dp_i=\max\{dp_j\}+1\),我们只需要将当前位置前面的最大值加一就是当前位置新的 \(dp\) 值。

又由于上面的性质,所以只会影响当前节点,对前后都没有影响。

接下来考虑插入操作,显然使用平衡树。

那么我们使用区间平衡树维护区间最大值,也就是维护 \(dp\)\(maxdp\)

此时两者的求法就很显然了。

[BZOJ3786] 星系探索

首先这是一个树上问题,并且不能用树剖简单求解。

考虑将这棵树转化为序列。那么常用方式有两种,DFS 序和欧拉序。

经过一点点推理可以发现,欧拉序实现起来较为简单。

如果你学过树上莫队,那么应该对欧拉序的处理方式比较熟悉。将第一次出现的位置 \(st_i\) 记为正,第二次出现的位置 \(ed_i\) 记为负。

于是查询操作就很简单了,对区间 \([1,st_i]\) 求和即可。

同时子树修改也应该较为简单,将区间 \([st_i,ed_i]\) 内的元素加上 \(q\) 即可。

现在就剩下换父亲了。经过模拟以及一些感性理解可以得到,将 \(x\) 的父亲换成 \(y\) 在欧拉序上表现为将区间 \([st_x,ed_x]\) 移到 \(st_y\) 的后面。

(其实也可以是移到 \(ed_y\) 的前面,区别就在于你接到哪个子树上)

对于这种平移区间的问题,考虑平衡树求解。

Splay 可以维护,但是 FHQ-Treap 可以直接分裂合并,比较方便。

剩下的全是细节了。

(好像这是一个数据结构叫 ETT)

  • 注意要开 long long

[hdu6647] Bracket Sequences on Tree

首先,我们发现,两颗同构的树所得出的方案数是一样的。

那么我们考虑换根求树哈希值的思路。首先设 \(f_i\) 表示第一次遍历以 \(i\) 为根的方案。那么根据上面的结论,会有方程:

\[f_i=\frac{deg_i!}{\prod dif_i!}\prod f_{to} \]

其中 \(dif_i\) 表示 \(i\) 的每个同构子树的数量,利用树哈希求解即可。

这样 dp 完一遍后,我们考虑换根。换根方式与哈希是相同的,排除掉子树贡献然后加上去即可。

剩下的就是细节问题了。注意有取模,除法需要用逆元。

[ABC300E] Dice Product 3

我们设 \(f(i)\) 表示得到 \(i\) 数的概率,那么有状态转移方程:

\[f(i)=\dfrac 16(f(i)+f(\frac i2)+f(\frac i3)+f(\frac i4)+f(\frac i5)+f(\frac i6)) \]

我们发现这个式子有点鬼畜,所以移项得

\[f(i)=\frac 15(f(\frac i2)+f(\frac i3)+f(\frac i4)+f(\frac i5)+f(\frac i6)) \]

显然我们不能直接暴力 dp,所以考虑记忆化搜索。用 map 记录 \(f(i)\) 的值。

[CF869C] The Intriguing Obsession

首先我们要看到,为什么题目中要求最短路长度是 \(3\),为什么不是 \(4,5,114514\) 呢?

经过画图可以发现这样一条性质:一个点不能连两个颜色相同的岛。

因此,只能是 \(a-b,b-c,a-c\) 这样连。此时我们又会发现,这三种情况是独立的,因此分开计算乘起来即可。所以这就是题目中只能用 \(3\) 的原因。

我们考虑一种情况即可,运用组合数学可以简单得到:

\[ans=\sum_{i=0}^{\min(a,b)}C_a^i\times C_b^i\times i! \]

直接求解即可。

[CF1525E] Assimilation IV

首先我们由期望的线性性质可以把答案拆成每个点的单独概率。

那么现在问题就是如何求出这个概率。我们发现直接求不好求,正难则反。

我们考虑第 \(i\) 个点不被选到的概率。在选择第一个城市的时候,我们只能选与它距离为 \(n+1\) 的;第二个城市可以选距离 \(n\) 的,也可以选剩下的距离 \(n+1\) 的;第三个,第四个……第 \(n\) 个都同理。

于是记 \(num(i,j)\) 表示距离第 \(i\) 个点 \(j\) 的城市个数。那么对于一点不被选到的方案数就易得了。将这个数除以 \(n!\) 就是不被选到的概率。用 \(1\) 减去然后累加就是最后的答案。

[CF517A] Lengthening Sticks

首先正难则反,我们先求出总方案数。

我们枚举 \(L\),然后考虑使用插板法。对于 \(i\in [1,L]\),总方案数都要加上 \(C_{i+2}^2\)

然后接下来我们看不合法方案数,我们考虑每一条边作为最长边。这里不妨设为 \(a\)

我们继续枚举给 \(a\) 加上的长度,那么为了使 \(b,c\) 的长度达不到两边之和大于第三边,给 \(b,c\) 的长度就应该是 \(\min(L-i,a+i-b-c)\)

所以不合法方案数就是:

\[\sum_{i=0}^LC_{\min(L-i,a+i-b-c)+2}^2 \]

把三条边都枚举一下即可。最后用总方案数减去这个式子就行了。

[ABC323E] Playlist

首先发现这个题求的是概率,因此考虑顺推。设 \(dp(i,j)\) 表示在第 \(i\) 时刻,第 \(j\) 首歌刚开始放的概率,那么会得到一个朴素的转移方程:

\[dp(i,j)=\sum_{k=1}^n dp(i-T_k,k) \]

显然复杂度为 \(O(Xn^2)\),无法通过。

不过这个式子的右边和 \(j\) 居然没有关系!那我们直接先暴力算出右边的式子,然后枚举 \(j\) 赋值即可。

那么最后的答案就是 \(\sum\limits_{i=X-T_1+1}^X dp(i,1)\),初始将所有 \(dp(0,i)\) 设为 \(\dfrac 1n\) 即可。

[CF261B] Maxim and Restaurant

首先将期望拆成每一个人的期望,然后对于每一个人,考虑用合法方案数除以总方案数。

我们枚举第一个进不去的人 \(x\),然后算出前面有多少个人,排列一下计算即可。接下来看具体实现。

\(dp(i,j,k)\) 表示枚举到第 \(i\) 个人,选了 \(j\) 个人,总体积达到 \(k\) 的方案数。其实这就是一个背包。

那么方程是 \(dp(i,j,k)=dp(i-1,j-1,k-a_i)+dp(i-1,j,k)\)

接下来我们考虑对于一个固定的 \(x\) 统计答案。枚举前面进去的人数 \(j\) ,同时为了让 \(x\) 进不去,体积范围应该是 \([p-a_x+1,p]\),那么对于 \(x\) 的答案就是:

\[\sum_{j=1}^{n-1}\sum_{k=\max(0,p-a_x+1)}^p j!\times (n-1-j)!\times dp(n,j,k)\times j \]

其中两个阶乘是任意排列剩下的数,乘上的 \(j\) 就是这个 \(x\) 做出的贡献。

累加计算即可,此时算出来的是合法方案数,需要除以 \(n!\)。注意 \(dp(i,j,k)\) 不能一次枚举完,因为要排除掉 \(x\)

同时需要特判所有人都能坐下的情况,而且数据不取模,你要么直接用 double 要么开 long long

[CF1777D] Score of a Tree

一道十分有意思的性质题。

先规定 \(d_i\) 表示 \(i\) 的子树的深度。

首先我们先看这样一条结论:当 \(t>d_i\) 时,该节点一定是 \(0\)。简单推理即可得到,因为在 \(t=1\) 时所有叶子节点都是 \(0\) 了。

于是接下来我们考虑一个点在所有排列中是 \(1\) 的期望总和。

首先证明,在任意一种排列的任意 \(t\) 时刻的任意节点 \(x\),只要它还能成为 \(1\)(即 \(t\le d_i\)),变为 \(1\) 的概率就是 \(\dfrac 12\)

用数归可以证明:

首先,\(t=0\) 时显然成立。

那么对于 \(t=k\),总会有一些节点变为 \(1\) 的概率是 \(\dfrac 12\),那么当 \(t=k+1\) 时,其父亲节点变为 \(1\) 的概率也就为 \(\dfrac 12\)

因此得证。

也就是说,只要这个节点还能被选上,那么它的期望就是 \(\dfrac 12\)

接下来将一个节点能被选上的情况乘上去,总的期望就是 \((d_i+1)\times \dfrac 12\)

最后求和,再乘上所有的排列就是 \(2^n\times \sum\limits_{i=1}^n(d_i+1)\times \dfrac 12=2^{n-1}\times\sum\limits_{i=1}^n(d_i+1)\)

[ABC297F] Minimum Bounding Box 2

首先我们会有这样一个容易假/难以实现的做法:枚举矩阵大小,然后在保证矩形大小的前提下看选点的个数。

这种方法直接做会很难,于是我们可以考虑容斥计算。下面讲解一种更加通用的容斥算法。

首先我们将一个矩形的分数期望拆成每一个点的分数期望,于是就变为一个点能被覆盖到的矩形个数之和。

发现这样做也不好做,所以再考虑容斥。我们考虑计算不被选上的方案。

此时所有点肯定在这个点的同一边,也就是同在上面,下面,左面,右面。方案数为:

\[C_{(i-1)\times m}^k+C_{(n-i)\times m}^k+C_{(j-1)\times n}^k+C_{(m-j)\times n}^k \]

但此时如果这些点都在左上角,右上角,左下角,右下角的话,方案数都会被多算一次。这种情况的方案数为:

\[C_{(i-1)\times (j-1)}^k+C_{(i-1)\times (m-j)}^k+C_{(n-i)\times (j-1)}^k+C_{(n-i)\times (m-j)}^k \]

此时总方案数为 \(C_{n\times m}^k\)。因此整个矩形的方案数总合为:

\[\sum_{i=1}^n\sum_{j=1}^mC_{n\times m}^k-C_{(i-1)\times m}^k-C_{(n-i)\times m}^k-C_{(j-1)\times n}^k-C_{(m-j)\times n}^k+C_{(i-1)\times (j-1)}^k+C_{(i-1)\times (m-j)}^k+C_{(n-i)\times (j-1)}^k+C_{(n-i)\times (m-j)}^k \]

最后用这个方案数除以 \(C_{n\times m}^k\) 就是期望了。

[CF696B] Puzzles

首先设 \(E(x)\) 为枚举到点 \(x\) 的步数期望,那么显然 \(E(x)\)\(E(fa)\) 转移而来。

接下来就是转移时期望多走的步数,也就是其它子树的期望。这里如果直接计算显然不行,但是我们可以对于每一颗子树都拆开计算。

对于一个子树,他在 \(x\) 前面遍历到的概率都是 \(\dfrac 12\),所以总的期望就是 \(\dfrac 12\sum\limits_{i\in son} siz_i\)

那么对于后半部分的求和,我们发现就是 \(siz_{fa}-siz_x-1\)

因此转移方程就是:

\[E(x)=E(fa)+\dfrac 12 (siz_{fa}-siz_x-1)+1 \]

DFS 进行树形 dp 即可。

[CF500D] New Year Santa Network

首先我们考虑每一条边对于期望的贡献。

那么只有这三个点时跨过了这条边时才会产生贡献。所以我们枚举子树大小 \(siz_i\),然后分情况讨论子树内时一个还是两个点。

此时这条边会被过两次,然后再除以总方案数可以得到对于一条边的期望贡献:

\[2\times\dfrac{C_{siz_u}^2\times (n-siz_u)+C_{(n-siz_u)}^2\times siz_u}{C_n^3}\times l_i \]

我们先求出所有边初始的期望和,然后每次修改直接减去差值即可。

[ABC243F] Lottery

看到 \(n\le 50\),说明要么是个 \(O(n^4)\) 大力枚举,要么是个其他的玄学算法。

我们考虑 dp,设 \(dp(i,j,k)\) 表示当前枚举到第 \(i\) 张卡片,抽了 \(j\) 次,获得 \(k\) 张不同卡片的概率。

那么我们可以直接大力 dp。

如果这张卡片不抽,那么有 \(dp(i,j,k)=dp(i-1,j,k)\)

否则,假设这张卡片抽了 \(l\) 次,那么概率为 \({p_i}^l\),同时这 \(l\) 次并不知道位置,所以还要乘上 \(C_j^l\)

因此转移方程为:

\[dp(i,j,k)=\sum_{l=1}^j dp(i-1,j-l,k-1)\times {p_i}^l\times C_j^l \]

初始化为 \(dp(0,0,0)=1\),结果为 \(dp(n,k,m)\)

[BZOJ4402] Claris的剑

前言:由于公式较多,不采用 \(C_n^m\) 的书写方式,而采用 \(\binom{n}{m}\) 的书写方式。

超级牛逼的一道组合数学题。

首先我们发现,题目中要求本质不同的数量,并且这个本质不同的定义还有点离谱。我们先考虑解决这个“本质不同”。

首先我们发现,对于一把剑,一定能将其排序成如下形式:

  • \(1,(2,1),(2,1),\cdots,2,(3,2),(3,2),\cdots,3,\cdots,j\)
  • \(1,(2,1),(2,1),\cdots,2,(3,2),(3,2),\cdots,3,\cdots,j,j-1\)

其中 \(j\) 为数列中最大的数。在上面的排列中,我们可以将一些相邻的数放在一起,变成二元组(即上面的括号)。

那么如果我们确定序列总长度 \(i\),最大值 \(j\),那么就相当于将 \(\lfloor\frac {i-j}2\rfloor\) 个二元组,放入 \(j-1\) 个空隙中。利用下面的引理 \(1\) 可以得到此时答案为 \(\binom{\lfloor\frac {i-j}2\rfloor+j-1-1}{j-1-1}=\binom{\lfloor\frac {i-j}2\rfloor+j-2}{j-2}\)

引理 \(1\):将 \(n\) 个元素放入 \(m\) 个盒子,可以为空。我们先给 \(n\) 个元素加上 \(y\) 个元素,然后插板,最后每个盒子中减去一个元素即可。因此结果为 \(\binom{n+m-1}{m-1}\)

此时总方案数为:

\[1+\sum_{i=2}^n\sum_{j=2}^{\min(m,i)}\binom{\lfloor\frac {i-j}2\rfloor+j-2}{j-2} \]

但是这么做复杂度是 \(O(nm)\),无法通过。我们考虑枚举 \(k=\lfloor\frac {i-j}2\rfloor\) 的值。

\[\begin{aligned} &1+\sum_{i=2}^n\sum_{j=2}^{\min(m,i)}\binom{\lfloor\frac {i-j}2\rfloor+j-2}{j-2}\\ =&1+\sum_{j=2}^{\min(n,m)}\sum_{k=0}^{\lfloor\frac{n-j}{2}\rfloor}\binom{k+j-2}{j-2}+\sum_{j=2}^{\min(n-1,m)}\sum_{k=0}^{\lfloor\frac{n-1-j}{2}\rfloor}\binom{k+j-2}{j-2}\\ \end{aligned} \]

注意,枚举 \(k\) 的时候要考虑上面数列的两种情况,因此有两部分。接下来我们再改枚举 \(j\) 为枚举 \(j-2\),改枚举 \(k\)\(k+j\),则得到答案为:

\[\begin{aligned}&1+\sum_{j=0}^{\min(n-2,m-2)}\sum_{k=0}^{\lfloor\frac{n-2-j}{2}\rfloor}\binom{k+j}{j}+\sum_{j=0}^{\min(n-3,m-2)}\sum_{k=0}^{\lfloor\frac{n-3-j}{2}\rfloor}\binom{k+j}{j}\\ =&1+\sum_{j=0}^{\min(n-2,m-2)}\sum_{k=j}^{\lfloor\frac{n-2-j}{2}\rfloor+j}\binom{k}{j}+\sum_{j=0}^{\min(n-3,m-2)}\sum_{k=j}^{\lfloor\frac{n-3-j}{2}\rfloor+j}\binom{k}{j} \end{aligned} \]

接下来需要再说明一个引理:

引理 \(2\)\(\sum\limits_{i=x}^y\binom{i}{x}=\binom{y+1}{x+1}\)。我们可以钦定在 \(y\) 中多出的那一个数字在哪一位之后,然后对这一位之前的所有数中选 \(x\) 个,再加上这个多出来的数就是在 \(y+1\) 个数中选 \(x+1\) 的数的方案数。

因此我们又可以将答案化为:

\[1+\sum_{j=0}^{\min(n-2,m-2)}\binom{\lfloor\frac{n-2-j}{2}\rfloor+j+1}{j+1}+\sum_{j=0}^{\min(n-3,m-2)}\binom{\lfloor\frac{n-3-j}{2}\rfloor+j+1}{j+1} \]

终于我们发现,这个式子能在 \(O(n)\) 的复杂度之内求出来了!接下来直接用组合数计算即可。

[CF466D] Increase Sequence

一道很有意思的题目。

首先,显然的一步是令 \(a_i\leftarrow h-a_i\)。接下来,由于考虑到区间的加法,因此我们用差分处理问题。

\(b_i=a_i-a_{i-1}\),目标就是让 \(b\) 归零。

而一次区间 \([l,r]\) 的操作可以让 \(b_l\) 加一,\(b_{r+1}\) 减一。由于 \(l,r\) 不能重复,因此当 \(|b_i|> 1\) 时,必须有几个区间重叠,因此此时直接输出 \(0\)

加下来分类讨论:

  • \(b_i=1\) 时,必然有一个区间的 \(l\)\(i\)。我们记录当前未被匹配的左端点数量 \(p\)。此时 \(p\) 加一。
  • \(b_i=0\) 时,可以不增加区间,也可以将 \(i\) 作为新的左端点,\(i-1\) 作为新的右端点。此时答案要加上答案乘 \(p\)
  • \(b_i=-1\) 时,必然有一个区间的右端点为 \(i-1\)。此时答案乘上 \(p\),同时 \(p\) 减一。

最后输出答案即可。

[CF559C] Gerald and Giant Chess

首先,发现朴素 dp 复杂度 \(O(hw)\),无法通过。

接下来我们会发现,\(n\le 1000\),这启示我们从黑色格子入手。

容易想到容斥,总方案数好求、经过一个点的方案数好求、经过两个点的方案数好求…… 然而复杂度是 \(O(2^n)\) 的,还不如 dp。

那如果将这两者结合起来呢?

我们设 \(dp(i)\) 表示走到第 \(i\) 个黑格的合法方案数,此时结合容斥原理即可得到转移方程:

\[dp(i)=\binom{x_i+y_i-2}{x_i-1}-\sum_{j=1}^{i-1}\binom{x_i-x_j+y_i-y_j}{x_i-x_j}dp_j \]

(注意此时应该现将坐标排序)

然后统计答案就很简单了,这里我们可以将点 \((h,w)\) 也当成黑格进行 dp,最后答案就是 \(dp(k+1)\)

[CF520E] Pluses everywhere

首先这道题来者不善,我们需要先证一个小引理:

引理:对于一个 \(a_i\),如果在 \(i\) 后面且离 \(i\) 最近的加号在 \(j\) 个数字后,那么他对答案产生的贡献就是 \(a_i\times 10^j\times C_{n-2-j}^{k-1}\)

首先,\(a_i\times 10^j\) 是易得的。后面的组合数的意义是:总共有 \(n-1\) 个插加号的位置,在这 \(j\) 个数字前不能插加号,同时已经在 \(j\) 个数字后插了一个了,因此总共还剩下 \(n-1-j-1=n-2-j\) 个空。

因此,我们可以暴力枚举上面的 \(i,j\) 进行计算。但是注意,当后面没有加号的时候,贡献是 \(a_i\times 10^{n-i}\times C_{i-1}^k\)。因此答案应该是:

\[\sum_{i=1}^{n}(\sum_{j=0}^{n-i-1}a_i\times10^j\times C_{n-2-j}^{k-1}+a_i\times 10^{n-i}\times C_{i-1}^k) \]

此时式子的求值是 \(O(n^2)\) 的,无法接受。我们发现,对于 \(j\) 相等的情况,他们乘的组合数是一致的。于是我们尝试枚举 \(j\) 可以得到:

\[\begin{aligned}&\sum_{i=1}^{n}(\sum_{j=0}^{n-i-1}a_i\times10^j\times C_{n-2-j}^{k-1}+a_i\times 10^{n-i}\times C_{i-1}^k)\\ =&\sum_{i=1}^{n}\sum_{j=0}^{n-i-1}a_i\times10^j\times C_{n-2-j}^{k-1}+\sum_{i=1}^{n}a_i\times 10^{n-i}\times C_{i-1}^k\\ =&\sum_{j=0}^{n-1}(\sum_{i=1}^{n-j-1}a_i\times 10^j\times C_{n-2-j}^{k-1})+\sum_{i=1}^{n}a_i\times 10^{n-i}\times C_{i-1}^k\\ =&\sum_{j=0}^{n-1}(10^j\times C_{n-2-j}^{k-1}\times \sum_{i=1}^{n-j-1}a_i)+\sum_{i=1}^{n}a_i\times 10^{n-i}\times C_{i-1}^k \end{aligned} \]

这时我们惊奇的发现,括号中的式子是 \(\sum\limits_{i=1}^{n-j-1}a_i\)。这不直接前缀和一下就行了吗!于是最后答案是:

\[\sum_{j=0}^{n-1}(10^j\times C_{n-2-j}^{k-1}\times \text{sum}_{n-j-1})+\sum_{i=1}^{n}a_i\times 10^{n-i}\times C_{i-1}^k \]

\(O(n)\) 求解即可。

[CF489F] Special Matrices

首先显然是 dp,问题在于状态。

我先想到的是设 \(dp(i,j)\) 表示枚举到第 \(i\) 行,有 \(j\) 列已经满足的方案。实际写下来不好实现。

于是考虑添加状态,我们考虑设 \(dp(i,j,k)\) 表示枚举到第 \(i\) 行,有 \(j\) 列放了 \(1\) 个,\(k\) 列一个没放。

那么我们首先来解决一个问题,显然 \(O(n^3)\) 空间会爆。但是显然 \(i\) 只和 \(i-1\) 状态有关,滚动数组即可。

第二个问题是,现在的时间复杂度也是 \(O(n^3)\) 的。不过没有关系,注意到 \(j\) 其实可以用 \(k\) 来表示,除此之外的 \(j\) 都没有贡献。

引理:\(j=2(n-i+1-k)\)

首先,保证前 \(i-1\) 行每行放了两个,于是就剩下 \(n-i+1\) 行。每行放两个,那么就要放 \(2(n-i+1)\) 个。

同时,接下来还要有 \(k\) 列,每列放两个,于是会要放下 \(2k\) 个。

因此剩下的可以放的就是 \(2(n-i+1)-2k=2(n-i+1-k)\) 个。由于 \(j\) 表示放了 \(1\) 个的列数,也就是还需要放 \(1\) 个的列数,因此 \(j=2(n-i+1-k)\)

此时我们就可以愉快 \(O(n^2)\) dp 了。

转移方程十分简单,分情况讨论:

  • 当两个都放在 \(j\) 上,会有 \(dp(j-2,k)\leftarrow dp(j,k)\times\dfrac{j(j-1)}{2}\)
  • 当两个都放在 \(k\) 上,会有 \(dp(j+2,k-2)\leftarrow dp(j,k)\times \dfrac{k(k-1)}2\)
  • 当两个一个放在 \(j\) 上,一个放在 \(k\) 上时,会有 \(dp(j,k-1)\leftarrow dp(j,k)\times j\times k\)

初始时以给定的矩阵为初始状态,答案为 \(dp(0,0)\)

[hdu5396] Expression

显然考虑区间 dp。

\(dp(i,j)\) 表示 \([i,j]\) 区间内结果的和。那么显然我们枚举断点统计答案。

接下来需要分类讨论中间的符号:

  • 当符号为 + 时,我们发现两边的 \(dp\) 值要乘上另一边合并的方案得到总方案,即 \(dp(i,j)=dp(i,k)\times (j-k)!+dp(k+1,j)\times (k - i)!\)。但是此时符号的顺序没有规定,因此还要乘上 \(C_{j-i-1}^{k-i}\) 得到最终答案。
  • 当符号为 - 时,同理。
  • 当符号为 * 时,两边的每一种结果相乘都会得到新的结果,因此有 \(dp(i,j)=dp(i,k)\times dp(k+1,j)\)。同时还要乘上 \(C_{j-i-1}^{k-i}\)

此题取模要取成正的,最后结果为 \(dp(1,n)\)

[hdu4661] Message Passing

首先考虑这样一件事:如何做才能达到最小值?

显然,假如我们规定一个根,那么让儿子把信息不断给父亲,最后根节点收到所有信息,然后再由根节点将信息给其他点。

这样做的操作次数是 \(2(n-1)\),不过这不是重点。我们需要求出方案数。

首先,我们要发现,所有点把信息给根节点和根节点把信息给所有点的方案数其实是一致的。我们只需要算出一个然后平方即可。

接下来,我们考虑树形 dp 求解。由于每个点都要当一遍根节点,因此还要换根 dp。

\(1\) 为根节点进行 dp。设 \(f(i)\) 表示 \(i\) 子树内信息传给 \(i\) 节点的方案数,\(siz_i\) 表示 \(i\) 子树内边的个数。

那么我们来看如何计算 \(f(i)\),对于一颗子树,它内部的方案数显然是 \(f(son_i)\),但是我们还需要安排这颗子树内每一次传递在整个树的操作中的位置。我们以边为切入点(一次操作可以看为一条边),总共有 \(siz_i\) 条边,这颗子树有 \(siz_{son_i}\) 条边,同时由 \(son_i\) 传递到 \(i\) 还需要一条边,因此总共需要操作的边数是 \(siz_{son_i}+1\)

我们可以以任意顺序考虑每一颗子树的顺序,每一次操作完可用的边数就会减少。将组合数与 \(f(son_i)\) 相乘,然后总体相乘,可以得到答案为:

\[f(i)=\binom{siz_i}{siz_{son_1}+1}\times\binom{siz_i-siz_{son_1}-1}{siz_{son_2}+1}\times\cdots\times\prod f(son_i) \]

爆拆组合数化简得:

\[f(i)=siz_i!\prod\frac{f(son_i)}{siz_{son_i}!} \]

相当于每一颗子树的贡献就是 \(\dfrac{f(son_i)}{siz_{son_i}!}\)

接下来考虑换根,其实很简单了,将自己这颗子树对父亲的贡献排除掉,然后加到自己身上即可。这个贡献在上面就得出了。但是注意细节较多,需要认真计算。

设换根后的答案为 \(g(i)\),最后的答案就是 \(\sum\limits_{i=1}^ng(i)^2\)

[CF1746D] Paths on the Tree

首先,我们发现,所有根链的节点一定为叶子结点,只有这样才会更优。

然后我们考虑如何分配这些边。由抽屉原理可知,对于一个节点 \(x\),他如果能经过 \(k\) 次,它的每个儿子至少要被经过 \(\lfloor\dfrac{cnt_x}{k}\rfloor\) 次。我们发现这是一个递归的定义,递归求解即可。

递归的边界在哪里呢?由于叶子结点最优,所以到叶子结点返回即可。

但是,对于那个点 \(x\),还会有 \(cnt_x\bmod k\) 个儿子会多经过一次。显然我们需要取前最大的这么多条边,因此递归结束要返回当前最大的链的和。

但是这样做,如果 \(x\) 取了一条最长边,它的父亲又取了同样的最长边,可能会导致答案错误。也就是说 \(x\) 选过的父亲不能再选,此时我们用一个优先队列维护子树最大链的值,将前 \(cnt_x\bmod k\) 个删掉,剩下的队头就是选完后子树最大链的值,以此避免重复。将这个值再返回给父亲即可。

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

[CF1579G] Minimal Coverage

显然考虑 dp,问题在于状态的设计。

首先考虑要记录那些元素,无非就是当前的坐标,最左的端点和最右的端点。

单独设复杂度会爆炸。我们考虑差值 dp,设 \(dp(i,j)\) 表示枚举到第 \(i\) 个线段,放下这条线段后坐标离最靠左的端点的距离为 \(j\) 时,距离最靠右的端点的距离。

那么我们分类讨论,初始状态为 \(dp(0,0)=0\)

  • 当放下 \(i+1\) 条线段时,向左放,则有 \(dp(i+1,\max(j-a_{i+1},0))=\min\{dp(i,j)\}\)
  • 当放下 \(i+1\) 条线段时,向右放,则有 \(dp(i+1,j+a_{i+1})=\min\{\max(dp(i,j)-a_{i+1},0)\}\)

那么最后就只剩下两个问题了,首先考虑 \(j\) 的范围。设 \(\text{mx}\) 为所有线段长度最大值,这时我们发现,最优解的长度一定在 \([1,2\times \text{mx}]\)(显然可以做到,当前端点为正数时向左放,端点为负数时向右放即可满足条件)。因此 \(j\in[1,2\times \text{mx}]\)

接下来考虑答案,其实就很简单了,为 \(\min\limits_{i=1}^{2\times \text{mx}}i+dp(n,i)\)

[CF1743E] FTL

首先,我们发现 \(h\le 5000\),但是 \(t_i\le 10^{12}\)。因此我们只能以 \(h\) 为状态。

\(dp(i)\) 表示当前造成了 \(i\) 点伤害所用的时间。那么我们首先考虑只使用一种武器的转移,枚举使用的武器 \(k\),会有:

\[dp(i+p_k-s)=\min\{dp(i)+t_k\} \]

接着考虑两种武器一起用的方式。我们首先枚举 \(j\) 表示武器 \(k\) 使用的次数,那么在第 \(j\) 次的时候两者一起发射。

  • 此时武器 \(k\) 的单独使用次数为 \(j-1\),造成伤害为 \((j-1)\times(p_k-s)\)
  • 此时武器 \(3-k\) 的单独使用次数为 \(\lfloor\dfrac{j\times t_k-t_{3-k}}{t_{3-k}}\rfloor\),造成伤害为 \(\lfloor\dfrac{j\times t_k-t_{3-k}}{t_{3-k}}\rfloor\times (p_{3-k}-s)\)

最后我们还要加上 \(p_1+p_2-s\) 作为这一次打击的伤害。

设这些总伤害 \((j-1)\times(p_k-s)+\lfloor\dfrac{j\times t_k-t_{3-k}}{t_{3-k}}\rfloor\times (p_{3-k}-s)+p_1+p_2-s=S\),则转移方程为:

\[dp(i+S)=\min\{dp(i)+j\times t_k\} \]

最后输出 \(dp(h)\) 即可。

[CF1249F] Maximum Weight Subset

首先状态很简单,设 \(dp(i,j)\) 表示以 \(i\) 为根的子树内选的点到 \(i\) 的距离中最短的恰为 \(j\) 的方案数。

那么我们可以直接暴力转移:

\[dp(x,\min(i,j+1))=\max\{dp(x,i)+dp(son_x,j)\} \]

方程很好理解。不过此题的重点不在这里。

我们发现,当 \(\min(i,j+1)=i\) 时,方程变为 \(dp(x,i)=\max\{dp(x,i)+dp(son_x,j)\}\)。此时 \(dp(x,i)\) 在自己更新自己,这是不被允许的,并且我们也没有别的方式避免。因此我们可以考虑用一个临时数组存下当前求解的 \(dp(x,i)\),最后统一赋值即可。

最后答案为 \(\max\{dp(1,i)\}\)

[CF895C] Square Subsets

首先此题有简单的线性基做法,但我不会。

我们考虑到这样一个事实:一个数是否为

完全平方数只与它的质因数数量是否全是偶数有关。

又发现 \(a_i\le 70\),而在 \(70\) 以内的质数恰好只有 \(19\) 个。

综合一下,我们只需要关注 \(19\)​ 个质数出现次数的奇偶性。显然使用状压 dp。

\(dp(i,S)\) 为枚举到 \(i\) 这个数字时,所有质数的奇偶性状态为 \(S\) 的方案数。

我们将 \(i\) 质因数分解,得到它的质数奇偶性状态 \(P\)。用 \(S\ \text{xor}\ P\) 得到 \(S'\)。然后分类讨论。

当选取奇数个 \(i\) 这个数的时候,我们的状态会变为 \(S'\)。同时,选取奇数个的方案数为:

\[C_{cnt}^1+C_{cnt}^3+C_{cnt}^5+\cdots=2^{cnt-1} \]

因此此时会有转移方程 \(dp(i,S')=dp(i-1,S)\times 2^{cnt-1}\)

同理可得当选取偶数个 \(i\) 时方程为 \(dp(i,S)=dp(i-1,S)\times 2^{cnt-1}\)

最后初始状态为 \(dp(0,0)=1\),但是这相当于算上了空集,因此答案为 \(dp(70, 0)-1\)

完了吗?不,由于 \(dp\) 数组需要开 long long,于是经过计算发现,\(\dfrac{70\times 2^{19}\times 8}{1024^2}=280\)。然而题目空限仅有 \(256\)

发现 \(dp(i)\) 的值只与 \(dp(i-1)\) 有关,滚动数组优化即可。

同时此题也较为卡常,所以需要预处理 \(2\) 的幂、分解质因数时及时 break 等等。

[CF1874C] Jellyfish and EVA

首先显然考虑概率 dp,设 \(dp(i)\) 表示从 \(i\) 走到 \(n\) 的概率。

现在考虑转移。首先显然会有 \(dp(i)=\sum\limits_{j\in to}p(i)dp(j)\)

我们贪心的想,\(p(i)\) 大的应该对 \(dp(j)\) 大的,现在问题就在于如何求 \(p(i)\)

\(f(i,j)\) 表示当前点有 \(i\) 个出边,按照概率从大往小选,只能被迫选到第 \(j\) 大的概率。

这个状态看上去很炸裂,我们继续来看。首先 \(f(i,1)=\dfrac 1i\),表示当前我们选到 \(1\) 号点,对面选到 \(1\) 号点的概率。

接下来看 \(f(i,j)\),我们考虑从上一个状态转移。

  • 假如对面选到 \(j\) 后面的点,有两条边会一起炸掉。于是炸掉两条边的概率为 \(\dfrac{i-j}{i}\)。此时原先的 \(j\) 号点就变成了 \(j-1\) 号点,所以此时概率为 \(f(i-2,j-1)\)​。
  • 假如对面选到 \(j\) 前面的点(但不是我选的点),有两条边会一起炸掉。于是炸掉两条边的概率为 \(\dfrac{j-1}{i}\)。此时原先的 \(j\) 号点就变成了 \(j-2\) 号点,所以此时概率为 \(f(i-2,j-2)\)

因此转移方程为:

\[f(i,j)=\dfrac{i-j}i\times f(i-2,j-1)+\dfrac{j-1}i\times f(i-2,j-2) \]

先预处理出 \(f(i,j)\),然后 \(dp\) 转移即可。

[CF1139D] Steps to One

牛逼数论题。

首先考虑设 \(dp(i)\) 表示当前 \(\gcd\)\(i\) 之后,还需要加入数字的期望个数。

首先先推出一个暴力的转移方程:\(dp(i)=1+\dfrac 1m\sum\limits_{j=1}^mdp(\gcd(i,j))\)。统计答案时先枚举第一个放进去的数,然后答案就是 \(\dfrac 1m\sum\limits_{i=1}^mdp(i)+1\)

现在我们仔细看一下上面的方程。首先它是有问题的,当 \(i\mid j\) 时,\(\gcd(i,j)=i\),此时 \(dp(i)\) 会自己更新自己。因此我们需要将它提出来得到 \(dp(i)=1+\dfrac 1m\sum\limits_{j=1,i\nmid j}^mdp(\gcd(i,j))+\dfrac 1m\times \lfloor\dfrac mi\rfloor dp(i)\),移项得到最后的方程为:

\[dp(i)=\dfrac{1+\dfrac 1m\sum\limits_{j=1,i\nmid j}^mdp(\gcd(i,j))}{1-\dfrac 1m\times \lfloor\dfrac mi\rfloor} \]

现在我们考虑优化这个方程。

我们先考虑设 \(f(i,j)=\sum\limits_{x=1}^m[\gcd(i,x)=j]\),即在 \(1\sim m\) 中有多少个数满足 \(\gcd(i,x)=j\)。那么原来的转移方程就可以化为:

\[dp(i)=\dfrac{1+\dfrac 1m\sum\limits_{j\mid i}^mdp(j)\times f(i,j)}{1-\dfrac 1m\times \lfloor\dfrac mi\rfloor} \]

现在问题在于如何求出 \(f(i,j)\),有两条路:莫比乌斯反演以及一个麻烦的数论推法。由于我不会莫反所以只能写后面那个。

先对 \(f(i,j)\) 进行一个基本的变形:

\[\begin{aligned}f(i,j)&=\sum\limits_{x=1}^m[\gcd(i,x)=j]\\&=\sum_{x=1}^m[\gcd(\dfrac ij,\dfrac xj)=1]\\&=\sum_{x=1}^{\lfloor\frac mj\rfloor}[\gcd(\dfrac ij,x)=1]\end{aligned} \]

现在我们进行这样一个操作:将 \(f(i,j)\) 的定义修改为 \(\sum\limits_{x=1}^j[\gcd(i,x)=1]\)。于是原先的 \(f(i,j)\) 就变为了 \(f(\dfrac ij,\lfloor\dfrac mj\rfloor)\)

考虑求出现在 \(f(i,j)\) 的值。观察式子发现就是要求 \(i\)\(x\) 的质因子没有交集。

现在看到上面那句话会想到什么?容斥原理。我们先分解出 \(i\) 的不同的质因子,设取出的一个质因子集合为 \(S\),那么我们会得到:

\[f(i,j)=y-\sum_{S,S\ne \varnothing}(-1)^{|S|+1}\lfloor\dfrac y {\prod S_i}\rfloor \]

其中 \(\lfloor\dfrac y {\prod S_i}\rfloor\)​ 就是交集数量。那么最后我们就能得到转移方程:

\[dp(i)=\dfrac{1+\dfrac 1m\sum\limits_{j\mid i}^mdp(j)\times f(\dfrac ij,\lfloor\dfrac mj\rfloor)}{1-\dfrac 1m\times \lfloor\dfrac mi\rfloor} \]

对于容斥原理的求解,我们注意到 \(m\le 500000\),不同的质因子数量最多只有 \(6\) 个,因此二进制暴力枚举即可。

时间复杂度 \(O(m\sqrt m)\)

[CF1900E] Transitive Graph

首先观察题目,不难发现不可能造出图 \(H\) 然后暴力。

但是经过尝试,我们可以画出样例的图 \(H\),此时我们发现当中有一些点构成了完全图,对于这些点我们可以简化为一个点。

这让我们想到了什么?tarjan 缩点!不过不能在 \(H\) 图上缩,我们经过分析又可以发现,在图 \(G\) 上的任意一个强联通分量,最后都会在图 \(H\) 上形成完全图。

因此我们在图 \(G\) 上进行 tarjan 缩点,这样原图就变成了一个 DAG。我们记录每个强联通分量内的点个数与权值之和,拓扑排序然后 dp 即可。

posted @ 2024-03-03 22:04  UKE_Automation  阅读(93)  评论(0)    收藏  举报