9月杂题

[ABC310F] Make 10 Again

分母是 \(\prod a_i\),只需求分子。

首先要发现投出了 \(10\) 以上的点数是无用的,所以只需考虑 \(10\) 以内的。

思考如何计数,发现转移依赖于前面的点数和的方案数,而且 \(10\) 很小,考虑状压 DP,设 \(f_{i,s}\) 表示前 \(i\) 个骰子,状态为 \(s\) 的方案数,转移不表。

\(s\leq M=2^{11}\),所以时间复杂度 \(\mathcal{O}(nM10^2)\)

[ARC174E] Existence Counting

怎么就没想到呢??一直想着直接计数,比较困难,正难则反,转化为:排列数 \(-\) 没出现 \(x\) 的排列数 \(-\) 字典序大于 \(P\) 的方案数 \(+\) 既没出现 \(x\) 字典序还大于 \(P\) 的方案数。转化后就比较基础了。

[ARC173C] Not Median

感觉还是不够。

直觉告诉我们,答案大多数都很小。

注意到答案很大的地方周围应该长这样 -+-+-+0-+-+-+,这告诉我们只需找到两个相邻的值又同时在 \(p_i\) 一侧的就好了。

每个点都往左右扫,复杂度看似 \(\mathcal{O}(n^2)\),但是其实在 \(i\)\(x_1,x_2\) 之间的所有数答案一定是 \(3\),这意味着每个数只会被扫一遍。所以时间复杂度 \(\mathcal{O}(n)\)

[ABC281G] Farthest City

将所有点按最短路分层,每层的节点只能和相邻层还有层内的节点连边。设 \(f_{i,j}\) 表示用了 \(i\) 个点,最后一层有 \(j\) 个点的方案。转移:

\[f_{i,j}=\sum\limits_{k=1}^{i-j}f_{{i-j},k}\times \dbinom{n-1-(i-j)}{j}\times 2^{\frac{j(j-1)}{2}}\times (2^k-1)^j \]

CF1476F Lanterns

典题,覆盖问题可以将状态设计成 \(f_i\) 表示前 \(i\) 盏灯能覆盖的最长前缀。

转移分三类:

  • 前面不能覆盖到 \(i\),直接不管 \(i\)\(f_i=f_{i-1}\)
  • 前面能覆盖到 \(i\)\(f_i=\max(f_{i-1},i+p_i)\)
  • \(i\) 向左,找到一个 \(f_j\ge i-p_i\) 最小的 \(j\),然后 \(j+1\sim i-1\) 全部向右,\(f_i=\max\{k+p_k\}\)

不知道为什么想这么久,明明这么简单。

[ARC154C] Roller

有 ARC182B 作为基础这题很容易想到做法,将相同的合并成一块,只需判断是否存在一个断点使得 \(a\)\(b\) 的子序列。

但是还需要空余的位置,可以是 \(a\)\(b\) 没出现的,可以是 \(b\) 中相邻的,也可以是 \(a\) 中相邻的。若没有空余位置则必须 \(a,b\) 完全相等。

细节一直写挂,数组还开小了。

P3214 [HNOI2011] 卡农

想不出来。

\(f_i\) 表示选了 \(i\) 个子集且满足条件的方案。考虑容斥,为了满足和前面的 \(i-1\) 个子集加在一起全是偶数,前面每种选法都唯一确定一种子集,方案数为 \(A_{2^n-1}^{i-1}\)

再减去 \(i\) 为空的情况,方案数为 \(f_{i-1}\)(去掉 \(i\) 之后能满足条件)。

再减去 \(i\) 和前面相同的方案。去掉 \(i\)\(j\) 后也能满足条件,\(j\)\(i-1\) 种取值,子集 \(i\)\(2^n-1-(i-2)\) 种取法,方案数为 \(f_{i-2}\times (i-1)\times (2^n+1-i)\)

最后输出 \(\dfrac{f_m}{m!}\)

P3577 [POI2014] TUR-Tourism

在无向图搜索树上 DP,没见过。

由题得树的深度不超过 \(10\),这启发我们用树上状压 DP(还是没见过)。

一个重要的性质:无向图 DFS 树上的非树边一定是回边,不存在横叉边。所以我们可以状压父亲的状态。

DP 过程较为复杂,不写。

P6381 『MdOI R2』Odyssey

通过质因数分解我们很容易判断是否能构成完美数对,但是信息在边上我们很难直接 DP。

但我们发现如果用哈希去表示每一条边,那么能与它配对的边的哈希值也是确定的。这启发我们设 \(f_{i,h_i}\) 表示以 \(i\) 为终点,最后一条边哈希值是 \(h_i\) 的答案,时间复杂度 \(\mathcal{O}(n\log n\times 11)\)

P8860 动态图连通性

很牛逼。

首先肯定要离线,然后多次询问的边只有第一次有用。

记边被询问的时间为 \(d_i\),没询问的视作 \(d_i=Q+1\)。将 \(d_i\) 作为边的边权,那么就是要找一条路径,使得将路径上的边的权值从大到小排序,字典序最小。

类似 「The classic problem」一样用主席树维护最短路。

CF464D World of Darkraft

需要注意到 \(k\) 种装备地位相同,所以只需计算一种装备最后乘 \(k\)。设 \(f_{i,j}\) 表示还剩 \(i\) 个怪兽,装备等级为 \(j\) 的期望。转移不表。

[ABC370F] Cake Division

不会倍增的菜鸟了属于是。

二分答案,记 \(f_i\) 为从 \(i\) 开始的一个连续段的结尾 \(+1\)(即下一个连续段的开头),那么就是从 \(i\) 开始跳 \(k\)\(f\) 看终点是否满足条件。这显然倍增。

P7603 [THUPC2021] 鬼街

减半警报器。

一次灵异事件的发生可以暴力给所有质因子 \(+y\),因为质因子个数很少。问题是什么时候统计答案。

对于一个 \((x,y)\) 的监控,记加入时其质因子已经发生了 \(s\) 次灵异事件,响警报的条件是 \(\sum\limits _{p}cnt_p\ge y+s\)。转化成 \(\sum \Delta cnt_p\ge y\)。那肯定至少有一个 \(p\) 满足 \(\Delta cnt_p\ge \lceil\frac{y}{d_x} \rceil\),我们将其设为阈值,当一个房间里有监控达到阈值时我们就拿出来 check 一下,这可以用优先队列实现。

如果 check 失败,我们让阈值变成 \(\lceil\frac{y-\sum\Delta cnt_p}{d_x} \rceil\),然后重新加入优先队列。不难发现, 每次阈值至少减少 \(\dfrac{1}{d_x}\),所以时间复杂度 \(\mathcal{O}(m\times d_V\log V\log n)\)

[ARC171C] Swap on Tree

每棵子树最多 \(siz+1\) 种取值,且新的数是什么不重要。设 \(f_{x,t,0/1}\) 表示以 \(x\) 为根的子树,与 \(x\) 相连的边断了几条边,和父亲的边是否断了的方案数。

\(f'_{x,t,0}\leftarrow f_{x,t-1,0}\times f_{y,s,1}\times t+f_{x,t,0}\times f_{y,s,0}\)

\(f'_{x,t,1}\leftarrow f_{x,t-1,1}\times f_{y,s,1}\times t+f_{x,t,1}\times f_{y,s,0}\)

初始化 \(f_{x,0,0}=1\)\(f_{x,1,1}=[x\ne 1]\)

P6383 『MdOI R2』Resurrection

其实就是联通块的根之间连边。

容易想到设 \(f_{x,i}\) 表示 \(x\) 上面还有 \(i\) 个点可供选择的方案数,但是不会做转移。

因为 \(x\) 的选择会使得 \(i\) 的限制发生变化,而且 \(x\) 与儿子的谁先与父亲切断对转移也有影响。平常的树形 DP 依赖于儿子的状态,而这里对父亲也提出要求。

考虑分析图的性质,然后就发现儿子连的边一定不会与父亲连的边交叉,要不连父亲,要不连父亲连的点的上面。分析出这点,然后就可以枚举父亲连的点进行转移了。

P6009 [USACO20JAN] Non-Decreasing Subsequences P

静态区间查询,考虑猫树分治。

如何合并两个前后缀信息,记 \(g_{i,j}\) 表示 \([i,mid]\) 里以 \(j\) 结尾的不下降子序列数量。将值域放到状态里即可合并。

P3523 [POI2011] DYN-Dynamite

二分答案,如何判定?

转化成满足条件的最小覆盖。(用最少的点)

如果一个子树的根到这个子树的关键节点的最远距离 \(\le mid\),那就可以选择根来覆盖整棵子树,但这样可能会重复覆盖,我们需要想一个方法减小多余的覆盖。因此我们设 \(f_i\) 表示 \(i\) 距离它子树内关键节点的最远距离,\(g_i\) 表示 \(i\) 到它子树内选定节点的最短距离。

初始化 \(f_i=+\infty\)\(g_i=-\infty\)

转移 \(f_i=\max \{f_j+1\}\)\(g_i=\min\{g_j+1\}\)

还有一些情况需要特判

  • \(f_i+g_i\le mid\) 时,\(i\) 子树已经无需覆盖,\(f_i=-\infty\)
  • \(f_i=mid\) 时,我们此时必须选择 \(i\),则 \(f_i=-\infty\)\(g_i=0\)\(tot++\)
  • \(g_i>mid\)\(d_i=1\) 时,说明这棵子树不能被子孙覆盖,需要留给父亲,\(f_i=\max(f_i,0)\)

贪心 + DP,根本做不出来。

P8292 [省选联考 2022] 卡牌

大于 \(\sqrt{V}\) 的质数最多在每个卡牌里出现一次,可以特殊考虑,将 \(n\) 个数分组,依据是自己具有的大于 \(\sqrt{V}\) 的质数。

对每个组预处理出 \(g_s\) 表示组内凑出质数集合为 \(s\) 的质数的方案。

然后对组做 DP,设 \(f_{s,i}\) 表示考虑了前 \(i\) 个组,凑出质数集合为 \(s\) 的方案数。如果该组的质数被询问了,则不能选空。否则可以选空。但是时间复杂度不对我去你的。

问题在于每个质数在不同的合法方案中会被选择不同次数,考虑正难则反,枚举不含的质数集合,使用容斥解决。设 \(f_{s,i}\) 表示前 \(14\) 个质数不含的集合为 \(s\),是第 \(i\) 个质数(\(i>14\))的倍数的有多少个,可以预处理出来,时间复杂度 \(\mathcal{O}(2^{14}\sum c_i)\)

P2150 [NOI2015] 寿司晚宴

仍然考虑设 \(f_{s,i}\) 表示含有的前 \(8\) 个质因子集合为 \(s\),且是第 \(i\) 个质因子的倍数有多少个。然后发现不太对啊。

正常考虑设 \(f_{s,t}\) 表示 A 选了 \(s\) 集合的质因子,B 选了 \(t\) 集合的质因子的方案数。对于存在大质因子的数,对其内部做 DP,方法同上。

CF1810F M-tree

先考虑单次询问怎么做。可以二分答案,然后让每个点尽量往深度大的放。这样就可以得出答案 \(x\) 满足的充要条件就是 \(m^x\ge \sum\limits_{i=1}^nm^{a_i}\)。所以答案就是 \(\lceil\log _m \sum\limits m^{a_i}\rceil\)。这可以用线段树维护 \(m\) 进制实现。

P6576 [BalticOI 2017] Plus Minus

思考怎么才能固定整个矩阵,需要固定第一行和第一列。考虑什么时候才合法,发现必须第一行或者第一列是正负交错的。

然后你又发现,当第一行是交错的时候,每一行都是交错的。列同理。所以这时候就可以容斥计数了。

P5188 [COCI2009-2010#4] PALACINKE

这是一道挺困难的题。

首先不管买东西种类的限制,设 \(f_{u,i}\) 表示走到 \(u\) 点,用了 \(i\) 时间的方案数。构造矩阵

\[Ans=[f_{1,i-1},f_{2,i-1},\cdots,f_{1,i},f_{i,2},\cdots,ans] \]

转移矩阵自己想。那么在没限制的时候可以直接矩阵快速幂进行转移。

现在如果有了限制那该怎么办?考虑容斥,用总方案数减去不合法的方案数。每次只保留是选定集合子集的边。时间复杂度 \(\mathcal{O}(2^4n^3\log t)\)

反思:正常写出 DP 是带状态 \(s\) 的。因为这个东西难做所以才去想容斥。在没有了这个限制之后,再根据数据范围联想矩阵快速幂。有一些其它的做法,从一个经典问题:

一张 \(n\) 个点的有向图,求从 \(1\) 开始走恰好 \(t\) 条边,回到 \(1\) 的方案数。其中 \(n≤25,t≤10^9\)

引出。这个问题的解决方法就是矩阵快速幂。但是此题更为复杂,不是恰好,边权也不一定为 \(1\),最后也要容斥。如何解决前两个问题??看 P3758P4159

P5664 [CSP-S2019] Emiya 家今天的饭

枚举菜的个数 \(k\)。先不管第三个条件,计算出用不同烹饪方法做出 \(k\) 道菜的方案数,然后容斥。

每次最多只有一种主要食材不满足条件。枚举主要食材 \(v\)。设 \(f_{i,j,t}\) 表示前 \(i\) 种烹饪方法,用了 \(j\) 种,食材 \(v\) 用了 \(t\) 种的方案数。答案减去 \(f_{n,k,k/2+1\sim k}\)。时间复杂度 \(\mathcal{O}(n^3m)\),可以获得 \(84\) 分。

瓶颈在于计算不合法方案的时候。

我们发现 \(f\) 的第二维只是帮我们确定食材 \(v\) 是否比其它的多,但我们不关心具体是多少。于是我们可以设 \(f_{i,j}\) 表示前 \(i\) 种烹饪方法,食材 \(v\) 比其它的多了 \(j\) 种。这样就是 \(\mathcal{O}(n^2m)\)

CF1980G Yasya and the Mysterious Tree

维护每个点到根的异或值 \(d_i\),查询即查 \(d_v\oplus d_u\oplus x\) 的最大值,若可以维护则可使用字典树查询。

不难发现修改操作只对深度为偶数的点产生影响,记录修改操作的总异或值 \(m\)。建立两棵字典树,分别维护偶数深度和奇数深度即可。

CF1994G Minecraft

考虑枚举每个位置填什么,一个关键的地方在于一个位置最多向前产生不超过 \(n\) 的进位(调和级数可证)。设 \(f_{i,j}\) 表示第 \(i\) 位向 \(i+1\) 位产生了 \(j\) 的进位。

转移时根据填的数算出 \(1\sim i-1\) 位产生的进位,然后转移即可。

CF1823F Random Walk

将每个点的期望写出式子 \(E_i=\sum\limits_{\exist edge(x,i)}\frac{1}{deg_x}{E_x}\)。特殊的,\(E_s\) 要加上常数项,不能从 \(E_t\) 转移到 \(E_i\),高斯消元,无法通过。

思考特殊性质,因为这是一棵树,于是考虑将每个点的期望写成和父亲有关的式子。

\(E_x=k_xE_{fa}\),一开始有 \(E_x=\frac{1}{deg_{fa}}E_{fa}+\sum\limits_{y}\frac{1}{deg_y}{E_y}\) 。将每个 \(f_y\) 替换成 \(k_yE_x\) 即可。

CF1495D BFS Trees

先考虑只有一个点怎么做,以 \(x\) 为起点 bfs,然后将图分层,然后应该可以直接乘一些东西。

然后就不会了。

注意到若 \(i\sim j\) 的最短路超过一条就无解。否则,必然最短路上的点都在生成树上。其余的,枚举其父亲,答案乘上满足条件的父亲个数即可。

CF1736E Swap and Take

观察到每个位置被覆盖的数的下标是单调递增的,于是设 \(f_{i,j,k}\) 表示 \(i\) 这个位置被 \(j\) 覆盖了,用了 \(k\) 次交换。

  • \(i\)\(i-1\) 一样,则 \(f_{i,j,k}=f_{i-1,j,k-1}+a_j\)
  • 若不同,观察到此时 \(j\) 必须大于等于 \(i\),不然为啥还会不同。于是 \(f_{i,j,k}=\max_{p=1}^{j-1} f_{i-1,p,k-(j-i)}+a_j\)

想出了差不多,但还是差最后一点。感觉自己分类分的太过细致反而影响了思考。

CF1981E Turtle and Intersected Segments

一个关键的地方在于如何缩减边数规模。注意到若三条线段两两相交,假设 \(a_1<a_2<a_3\),那么因为 \(a_3-a_1=a_2-a_1+a_3-a_2\),所以只有后两条边有用,也就是只需连相邻的两条边。

考虑用扫描线维护这个过程,每条线段在 \(l\) 加入,在 \(r\) 删除。每次加入时与它 \(a\) 值的前驱、后继连边,边数降至 \(\mathcal{O}(n)\),时间复杂度 \(\mathcal{O}(n\log n)\)

CF1493E Enormous XOR

果然是一个结论题。

若最高位不相同则直接输出 \(n\)\(1\)

否则,我们希望选择奇数个,这样最高位才能为 \(1\)

我们已知模 \(4\) 等于 \(0,1,2,3\) 的四个数连续异或会变成 \(0\)\(2i\oplus 2i+1=1\),所以选择其实是有限的,我们发现约束了条件的 \((x,y)\),答案就是就只有 \(x,y,x\oplus 1,y\oplus 1\) 四种。显然当 \(y=r\) 时最优。此时再判断一下 \(x\) 取哪就好了。

P8819 [CSP-S 2022] 星战

如何判断一个点是否可以「实现反击」,其实就是形成基环森林。

「连续穿梭」则要求每个点出度为 \(1\)。所以只需全部点出度均为 \(1\) 就可以。

如何维护,使用和哈希

具体的,给每个点随机一个权值 \(w\),我们维护所有边的起点构成的可重点集,只需判断集合 \(w\) 之和是否等于 \(\sum\limits_{i=1}^n w_i\) 即可。

[ARC160F] Count Sorted Arrays

这它喵是人想出来的吗??

有一种 01 串的经典技巧:把小于等于 \(x\) 的设为 \(1\),大于 \(x\) 的设为 \(0\)。那么一个排列就对应着 \(n+1\) 个 01 串。一个排列有序当且仅当这 \(n+1\) 个 01 串都有序。01 串在变化的时候,最多有一个 \(0\rightarrow 1\)

假设我们得到了 01 串 \(i\) 经过操作后得到的新串 \(f_i\)。考虑对 01 串计数,设 \(dp_i\) 表示已经选了 $\operatorname{popcount}(i) $ 个 \(01\) 串,最后一个是 \(i\) 的方案数。转移即 \(dp_i\leftarrow dp_{i\oplus 2^j}\)。但要保证 \(i\) 现在是有序的,即 \(f_i\) 所有的 \(1\) 都在最前面。

每次操作,若所有排列的 \(x,y\) 都有序了就不操作。时间复杂度 \(\mathcal{O}(n^32^n)\)

[ABC328G] Cut and Reorder

套路的设 \(f_{s}\) 表示 \(s\) 集合里的数匹配了 \(b\) 的前 \(\operatorname{popcount}(s)\) 位,但是我不会转移,觉得交换操作带来的影响剩下的数的相对顺序很难搞。

但其实我们肯定只用一次交换操作就达到最优的排列,所以我们可以直接 DP 维护这个过程。每次找到一段连续区间接上 \(s\)。可以证明时间复杂度是 \(\mathcal{O}(n2^n)\)

CF1530F Bingo

容易想到容斥,计算满足所有行列对角线都至少有 \(1\)\(0\) 的情况,于是就有了 \(\mathcal{O}(n4^n)\) 的做法。

先考虑只有列的情况。再次容斥,用全部情况减去至少一列全为 \(1\) 的概率,再加上至少两列全为 \(1\) 的概率……

然后在计算列的同时枚举行计算行的概率。设 \(g_{i,s}\) 表示第 \(i\)\(s\) 集合位置为 \(1\) 的概率,然后我们只需要保证行不全为 \(1\) 就行了,那么一行的贡献就是 \(g_{i,s}-g_{i,2^n-1}\)

枚举对角线的状态,时间复杂度 \(\mathcal{O}(2^{n+2}n)\)

[ABC319G] Counting Shortest Paths

想着先求出最短路,但是只会 \(\mathcal{O}(n^2)\)

想到用 set 维护未被访问的点,但是没想到可以只走要删除的边然后再求补集。然后这样就可以求出最短路。

然后按照最短路分层,先让每个 \(v\) 加上满足 \(dis_u+1=dis_v\) 的所有 \(f_u\),然后再减去多余的。

时间复杂度 \(\mathcal{O}(m\log n)\)

P11071 「QMSOI R1」 Distorted Fate

考虑线段树维护区间内的数二进制下每一位的 \(1\) 个数。

修改操作相当于将 \(01\) 个数反转。

查询操作考虑每一位的贡献,二分出第一个 \(i\) 使得 \(cnt_1(l,i)\ge 1\),贡献就是 \(2^i\times (r-i+1)\)

时间复杂度 \(\mathcal{O}(n\log n\times 30)\)。空间复杂度貌似过不了但还是过了。

进一步的优化是,维护每一位的与、或,然后也比较简单。

P9220 「TAOI-1」椎名真昼

博弈论!

发现最多一个回合即可确定胜负。

A 赢就是要找一个黑点,操作一次就全白,可以 tarjan + 拓扑 + 搜索实现。

B 赢只有三种情况:

  • 全白。
  • 两个孤立黑点。
  • 一个黑点连向一个白点。

P9871 [NOIP2023] 天天爱打卡

\(f_{i,0/1}\) 表示到第 \(i\) 天,这一天不跑/随便的最高能量。枚举一个跑步连续段的起点 \(j\),然后 \(f_{j-1,0}+val(i,j)-(i-j+1)\times d\rightarrow f_{i,1}\)。其中 \(val(i,j)\) 表示所有满足 \(i\le x_k\le y_k\le j\)\(v_k\) 和。使用线段树优化,每次加入一个 \(i\) 时给 \([0,i)\) 全部减去 \(d\),然后给 \(r_k=i\) 的所有 \(j<l_k\)\(j\) 全部加上 \(v_k\)。然后查询 \([i-k,i)\) 的最大值转移到 \(f_{i,1}\),再将 \(f_{i,0}\) 加到线段树。时间复杂度 \(\mathcal{O}(n\log n)\)

发现只有段上的点有用,对端点离散化后套用上述做法,时间复杂度 \(\mathcal{O}(m\log m)\)

P6879 [JOI 2020 Final] スタンプラリー 3

一定要看数据范围做题

\(f_{i,j,0/1}\) 表示区间 \([i,j]\) 到达 \(i/j\) 的最小时间,但是不好转移,一开始想二分收集的数量,但是收集的雕像不一定连续。然后就不知道怎么处理时间和数量的依赖了。

发现这种状态的转移一般是 \(\mathcal{O}(1)\) 的,而 \(n\leq 200\),于是我们可以直接把数量放进状态里,这样就是 \(\mathcal{O}(n^3)\) 的状态,转移 \(\mathcal{O}(1)\),可以通过。

P10430 [JOISC 2024 Day1] 鱼 3

问题即用最少的单点减 \(D\) 次数 使得 \(c_{l\sim r}\) 单调不降。

暴力做法就是从 \(r\to l\) 直接贪心扫一遍。

考虑将询问离线,然后扫描线,每次加入一个 \(r\) 时就往前去暴力做。观察到如果我们更新了一对相邻的数,那之后它们的差不会变化。于是我们可以拿一个栈维护还没有更新过的地方,对一段连续段使用区间减法。这样复杂度均摊 \(\mathcal{O}(n\log n)\)

反思:好像啥都可以离线扫描线。

P8162 [JOI 2022 Final] 让我们赢得选举

有一个直观的想法,枚举协作者数量 \(t\),然后选 \(b_i\)\(t\) 小的城市找协作者,再从剩下的选 \(a_i\)\(k-t_i\) 小的来演讲。

但这是有问题的,可能一个 \(b_i\) 很小的地方 \(a_i\) 极其小。

于是我们加入一些 DP 来修改贪心。

\(f_{i,j}\) 表示前 \(i\) 个地方,选了 \(j\) 个协作者,其余地方直接演讲的最小时间。枚举总共协作者数量 \(t\) 这个东西是好 DP 的。然后再加上后面的贡献就好了。时间复杂度 \(\mathcal{O}(n^3)\)

反思:当贪心出现问题的时候,尝试使用 DP 来进行修正。

P9522 [JOISC2022] 错误拼写

牛魔计数题使我旋转。

主要说一下分析思路:

根据字典序的比较方式我们可以转化一下 \(T_{A_j}<T_{B_j}\) 这个条件。我们现在只考虑严格小于的情况。

字典序暗示我们要从后往前 DP,于是设 \(f_{i,j}\) 表示 \(s_i=j\) 的方案数。然后考虑从 \(f_{i',j'}\) 转移过来,思考转移的约束。

这个约束就是对于一段 \([A,B]\) 里面的 \(i'\),对 \(i<A\) 都要少掉一段贡献,这段贡献和 \(j\) 有关。

于是设 \(h_j\) 表示 \(i+1\sim n\)\(f_{*,j}\) 的贡献。每次移动 \(i\) 的时候更新 \(h_j\)。用链表维护,时间复杂度 \(\mathcal{O}(n|\sum|)\)

计数题好难。

長距離バス

发现每次赶走的人一定是一段区间。而这个区间的末尾必须紧跟着一个服务区,不然后面的人会被影响。

\(f_i\) 表示前 \(i\) 个人的最小代价。

如果不下车,\(f_{i}=f_{i-1}+W\times \left(\left\lfloor\dfrac{X}{T}\right\rfloor+[D_i\le X\bmod T]\right)\)

如果下车,考虑枚举这段下车区间的上一个人 \(j\),则 \(f_i=\min f_j+sumC(j+1,i)+W\times mt_i\times (i-j)\)。其中 \(mt_i\) 表示第 \(i\) 个人最快在啥时候可以下车。

对第二类转移使用斜率优化即可。

P9331 [JOISC 2023 Day1] Passport

线段树优化建图。

\(i\to [l_i,r_i]\) 连边。有种想法是将左端点和右端点分开考虑,但是一步可能同时向左右端点扩展,然后就不会了。

接下来就是注意力惊人了,我们注意到,在最优方案中,存在一个时刻,该时刻之前每一步同时向左右扩展,该时刻之后每一步只向一边扩展。

所以设 \(dis_x\) 表示从 \(x\) 分别向左右扩展加起来的最小护照,答案就是 \(\min dis_j+d(j,i)\)

建出反图,跑两次 dij 可以求出 \(dis_x\),然后新建源点向 \(i\)\(dis_i\) 的边,再跑一次最短路。

posted @ 2024-09-11 11:41  xishanmeigao  阅读(33)  评论(0)    收藏  举报