WEEK1

训练赛

A

今日已完成被 loj 4261 创飞大学习。

考虑转化题意变为,选出若干个点最大化点权和,且不存在两个点的距离 \(<k\)

显然有一个 dp,设 \(f_i\) 表示 \(0\sim i\) 的答案,转移为 \(f_i\leftarrow \max(f_{i-1},f_{i-k}+a_i)\)

然后可以获得足足 \(6\) 分(绷不住了)。

不难注意到我们只需要维护 \(k\) 个位置的 dp 值即可。

观察性质发现,\(a_i\) 由并非很多个连续段组成。考虑每个连续段。显然可以把每个连续段长度写成 \(pk+q\) 形式,只需要让答案加上 \(p\times a_i\) 并且 \(len\rightarrow q\) 即可。

现在所有连续段长度都 \(<k\) 了。直接用线段树大力维护这两种操作即可(动态开点或者离散化,这里我写的离散化)。

代码

B

今日已完成被 loj 4257 创飞大学习。

考虑把原序列搞成一些形如 \((a_i,b_i)\) 的对,其中 \(a_i\) 是值,\(b_i\) 是连续的 \(a_i\) 的个数。

然后假设我们现在一个一个插入这些对,我们可能会再插入之后产生一个谷。如果这个谷能够合并到其中一边我们就把他和过去,否则谷的两边独立,我们把这个谷扔到两边合并,并在中间插入一个大数。

不难发现,合并完之后这个序列的大小是 \(O(V)\) 级别的。

于是用线段树维护这个东西,修改直接在线段树上改,询问就把线段树的该区间提出来暴力合并。

这样做复杂度是 \(O(nV\log n)\) 的。

代码

C

今日已完成被 QOJ 9222 创飞大学习。

首先离散化,但是离散化的时候我们给相同值弄一个不同的权值。

显然如果 \(a_i>a_j,b_i<b_j\),我们在 A 买 \(i\),B 买 \(j\) 不优。

于是把这个东西扔到平面直角坐标系上,发现我们的选取方案形如,一条右上到左下的折线把这些点劈成两部分,左上部分全选 A,右下部分全选 B。

可以设一个 \(f_{i,j}\) 表示当前走到 \((i,j)\) 的最小花费是多少,为了转移可能还要加两个 \(0/1\) 进去。转移枚举折线的上一个位置即可。这样做是 \(O(n^2)\) 的。

我们可以对 \(a\) 倒着扫描线,然后发现这个转移实际上是一个整体 dp,直接用线段树大力维护即可。具体地,\(a\) 的贡献每次相当于一个前缀加,\(b\) 的贡献就是,当前已经扫到的,比这个位置的 \(b\) 小的所有的 \(b\) 之和。具体实现就是,\(a\) 直接在线段树上前缀加,\(b\) 只需要在计算右半边 dp 值的时候,加上左半边 \(b\) 之和即可(左右区间合并时也是这样)。

然后一个点的 dp 值就是线段树上的后缀 \(\min\),每次加的东西其实是一个三元组,形如 (\(0\) 位置加的值,\(1\) 位置加的值,加了几个数)。

代码

D

今日已完成被 luogu P10145 创飞大学习。

完全不搞笑的题。

先从特殊性质下手。本质上其实我们需要知道所有位置的值。

那么,对于一个线段树的子树里的点,我们有两种可能。第一种是我们已经知道了所有的值,第二种是还差一个不知道,这种我们就可以通过知道子树里最大的那个区间把它减出来。

然后有一个 dp,\(f_{i,0/1}\) 表示 \(i\) 子树内还有几个点不知道。

转移就是 \(f_{i,0}\leftarrow 2 f_{l,0}f_{r,0}+f_{l,0}f_{r,1}+f_{l,1}f_{r,0},f_{i,1}\leftarrow f_{l,0}f_{r,1}+f_{l,1}f_{r,0}\)

然后考虑一下我们在干什么,实际上我们是在分类。把被询问区间的覆盖情况分类(实现可以用哈希)。然后,两个不在同一类的点不能在线段树上出现的位置完全相同,否则就没救了。注意到这个相当于,把询问区间的覆盖情况分类后的若干个集合再次拆分得到线段树上的覆盖集合。

但是可能会有一类点完全没有被覆盖过,也就是说不需要求出来。

然后把上面那个 dp 扩展一下,设 \(f_{i,j}\) 表示 \(i\) 子树内还有 \(j\) 这个集合里的点不确定。特别地 \(j=0\) 表示全都确定了,\(j=1\) 表示不需要被确定的那个集合 还没被确定。转移同上。

发现一个 \(f_u\) 内有值的点不会太多,直接用 map 维护 dp 数组,然后启发式合并即可。

需要一个乘法标记。

代码

E

今日已完成被 luogu P5979 创飞大学习。

\(f_i\) 表示前 \(i\) 个人最大分几组,\(g_i\) 表示 \(f_i\) 最大的情况下的方案数,转移显然,可以轻松做到 \(O(n^2)\)

发现转移的位置完全没规律,所以一般的数据结构优化 dp 没救了,考虑 cdq 分治优化 dp。

\(\operatorname{len}(l,r)\) 表示 \([l,r]\) 中最大的 \(c\) 和最小的 \(d\) 组成的区间(区间未必合法)。

然后一个 \(j\) 能从 \(i\) 转移需要满足:

  • \(i<j\)

  • \(j-i\in \operatorname{len}(i+1,mid)\)

  • \(j-i\in \operatorname{len}(mid+1,j)\)

第一个限制天然满足。

我们发现对于第二个限制,一个确定的 \(i\) 事实上能转移到一段区间里。我们在区间的开头结尾分别挂上这个 \(i\),并用线段树维护 dp 值。

然后发现对于一个确定的 \(j\),能转移过来的 \(i\) 仍然在一个区间内,所以直接线段树区间查询即可。

代码

F

今日已完成被 QOJ 9254 创飞大学习。

发现众数出现次数等于 \(k\) 是不好做的,但是 \(\le k\) 是可以做的。

\(f_{i,j}\) 表示已经填了 \(i\) 个数,每次填数可以从 \(j\) 个数中选一个且众数出现次数不超过 \(k\) 的方案数。

想到转移 \(f_{i,j}\leftarrow f_{i-1,j}\times j\) 是简单的,但是发现根本就没有限制众数的出现次数。

因为我们钦定了该状态合法,所以唯一不合法的情况是,前面有若干种数已经出现了 \(k\) 次,然后这个位置又放了个这个数。

所以我们修改之后的转移是 \(f_{i,j}\leftarrow (f_{i-1,j}-f_{i-k-1,j-1}\times\binom{n-1}{k})\times j\)

注意到第二维实际上只有 \(\lfloor\dfrac{n}{k}\rfloor\) 个位置有用,所以直接做就是对的。

代码

G

今日已完成被 UOJ 37 创飞大学习。

首先我们发现强连通是非常难刻画的,我们考虑正难则反,刻画不强连通,显然就是搜索点后是一个拥有至少 \(2\) 个点的 DAG(可以不连通)。

首先有一个做法,暴力枚举每个点所在强连通分量的编号,然后 dp(先忽略复杂度炸掉了这个事实)。

\(h_{S}\) 表示点击为 \(S\) 的答案,\((S\rightarrow T)\) 表示点集 \(S\) 到点集 \(T\) 有多少条边。

再设 \(f_{S}\) 表示恰好 \(S\) 内的点的入度为 \(0\) 的方案数,\(g_{S}\) 表示钦定 \(S\) 内的点的入度为 \(0\) 的方案数。

显然有 \(g_{S}=h_{S-T}(T\rightarrow S-T)\),且 \(\displaystyle g_{T}=\sum_{T\subseteq S}f_{S}\)

反演得 \(\displaystyle f_{T}=\sum_{T\subseteq S}(-1)^{|S|-|T|}g_{S}\)

于是重写 \(h_{S}\),最后发现 \(\displaystyle h_{S}=\sum_{T\subseteq S,T\ne \emptyset}(-1)^{|T|+1}h_{S-T}2^{(T\rightarrow S-T)}\)

这个东西可以 \(O(3^n)\) 算,但是加上那一坨枚举的复杂度显然没救。

再设 \(f_{S}\) 表示 \(S\) 最终缩成一个点的方案数,\(g_{S}\) 表示 \(S\) 内的点最终缩成若干个无入度的点的方案数,然后再带上容斥系数(其实就是奇数个点的情况减去偶数个点的情况)。

于是 \(\displaystyle f_{S}=2^{(S\rightarrow S)}-\sum_{T\subseteq S,T\ne \emptyset}g_{T}2^{(T\rightarrow S-T)+(S-T\rightarrow S-T)}\)

然后 \(\displaystyle g_{S}=f_{S}-\sum_{T\subseteq S,T\ne S,\operatorname{lowbit}(T)=\operatorname{lowbit}(S)}f_{T}g_{S-T}\)。这是因为要钦定最后一个加入的,否则会算重,所以这里钦定最后一个加入的 \(\operatorname{lowbit}\) 相同。且因为后面又加入了一个强连通分量,所以整个部分的容斥系数相当于取反了,所以是减去后面那一坨而不是加上。

但是发现 \(f,g\) 的转移互相调用。仔细思考一下发现只有 \(f_{S}\) 会用到 \(g_{S}\),此时 \(g_{S}\) 中有一个 \(f_{S}\),但是这个 \(f_{S}\) 是不应该被减掉的,所以 \(g_{S}\) 中不加入这个 \(f_{S}\) 算出来的 \(f\) 是对的,只需要算完 \(f\) 再算 \(g_{S}\)。这个是对的是因为,你的 \(T\) 相当于是在枚举零入度强连通分量,如果整个就是的话那就不用减掉。

至于 \((S\rightarrow T)\) 一类的东西,是好算的,直接看代码实现即可。

代码

H

今日已完成被 QOJ 7645 创飞大学习。

显然我们一种有三种走法,第一种是 \(0\) 为左端点,第二种是 \(0\) 为右端点,第三种是 \(0\) 被包在中间。

我们给出结论,不存在两个第三种的区间仅仅有交,原因是可以调整成一个第一种和一个第二种。

于是搞一个区间 dp,设 \(f_{l,r}\) 表示已经干掉了 \([l,r]\) 中的商店最小要几天,同时存不完整的一天的最小花费时间,相当于一个 pair。

转移直接枚举是左端点左移还是右端点右移即可,时间复杂度 \(O(n^2)\)

代码

I

今日已完成被 QOJ 7644 创飞大学习。

我们暂时认为一个匹配边在上方和在下方是两种方案。

\(f_n\) 表示 \(n\) 对点匹配的方案数,显然 \(f_n\leftarrow\sum\binom{n\times 2}{i\times 2}\times \operatorname{catalan}(i)\times \operatorname{catalan}(n-i)\)

再设 \(g_n\) 表示 \(n\) 对点,且只有一个连通块的方案数(如果两条匹配边可以有交就认为它们之间有一条边,这里不认为边在上或者下是两种方案),但是我们并不会求 \(g_n\)

然后设 \(h_{n,m}\) 表示放了 \(n\) 个连通块,\(m\) 对点的方案数。有 \(h_{n,m}\leftarrow\sum h_{n-1,m-k}\times f_k\)

于是我们有 \(f_n\leftarrow\sum 2\times g_i\times h_{i\times 2,n-i}\),这个东西的意义是先钦定 \(1\) 所在连通块大小,剩下的放在 \(1\) 连通块的点的间隙里。

上式可以推出 \(2\times g_n\leftarrow f_n-\sum 2\times g_i\times h_{i\times 2,n-i}\)

下面我们认为一个匹配边在上方和在下方不是两种方案,即略微改写 \(f,h\) 的定义。

\(f\) 的转移仍然枚举 \(1\) 所在连通块大小,\(h\) 转移根本不变。然后发现这两个东西事实上转移不会互相调用,所以直接做就对了。

代码

J

今日已完成被 QOJ 7606 创飞大学习。

我们有两个做法,其中一个是 gsc0618 给出的,狠狠膜拜了。

做法 A:

考虑数位 dp,设 \(f_{u,sum,d}\) 表示当前还剩 \(u\) 位没有填,数字和是 \(sum\),距离上一个必败点的距离为 \(d\)

显然这个 \(d\) 不会很大,因为一个数的可转移范围不超过数字和,如果可转移范围内没有必败点,那么这个点必败。

于是从最后一位开始往上填数即可。

注意代码里当 \(u=0\) 的特判时的 \(d\) 事实上是上一个数距离必败点的距离。

代码 A

做法 B:

\(f_{l,r}\) 表示是否 \([l,r]\) 内没有必败点,显然若 \(l>r\) 则返回 \(1\)

否则返回 \(f_{r-s_r,l-1}\operatorname{xor} 1\)

但是我和 gsc0618 均无法给出复杂度证明,但是此做法能够通过,故仍然放在这里。

代码 B

K

今日已完成被 QOJ 6331 创飞大学习。

考虑设 \(f_{s,i,j}\) 表示当前还剩 \(s\) 的珠宝没有取,两个人分别在 \(i,j\),先手减去后手的最大值是多少。

转移就是 \(f_{s,i,j}\leftarrow\max (w_k-f_{s+id_k,j,k})\)

我们只需要不断尝试转移,直到某一次转移之后的结果不变,不难发现对于每个 \(s\) 至多转移 \(n\) 次。

代码

L

今日已完成被 luogu P3554 创飞大学习。

首先二分是套路的。

然后注意到一个事情,B 是不可能走回头路的,因为如果走回去能赢的话,那么一开始就走显然更能赢。

所以我们考虑一个事情,如果当前把 \(u\) 的儿子染完了,但是还有剩余次数,我们就可以支援 \(u\) 子树里的点(因为支援外面的点没有意义)。

于是有一个 dp,\(f_u\) 表示 \(u\) 子树需要多少次支援(可能是负数,代表还能支援多少次),有转移 \(\displaystyle f_u\leftarrow son_u-k+\sum_{v\in son(u)}\max(f_v,0)\)。合法条件是 \(f_1\le 0\)

这里和 \(0\)\(\max\) 的原因是,子树内能支援的次数不可能去支援子树外。

代码

posted @ 2025-08-28 08:54  zxh923  阅读(11)  评论(0)    收藏  举报