💡

逆天记录 - 3

创建于 2023-09-14

Tags: 好题

P9531 [JOISC 2022 Day4] 复兴计划

首先有结论:对于每条边,在最终方案中会被选择的 XX 是一个区间。

将所有的边按照边权排序,那么他被选择的代价关于 XX 是一个绝对值函数。对于每条边,找出前一条能与他形成环的边,那么分界的 XX 就是两条边边权的平均值。

找出每条边的 pre 可以在 O(nmα(n))O(nm\alpha(n)) 的复杂度内完成,并将询问离线,按照 XX 排序后维护一堆一次函数的和即可。

CF1801E Gasoline prices

对于每一个形如 {(u1,v1),(u2,v2)}\{(u_1,v_1),(u_2,v_2)\} 的限制,等价于将两条路径上对应点并查集合并,最后在同一个并查集中的元素的值必须相等,因此在求出最后并查集的合并情况后,只需要求出每个并查集连通块内部 LLmax\maxRRmin\min 即可,这一部分是容易计算的。

接下来考虑如何在合理的复杂度内计算出并查集的合并情况。

首先发现,将所有点全部合并联通只需要进行 n1n-1 次合并操作,因此有效的合并操作是 O(n)O(n) 的,只需要依次找到有效的合并操作即可。

考虑将每个点赋值上他所在并查集的祖先的点权,每次产生一个新的限制时,可以二分两条链上权值组成的序列的 LCP,第一个不同的位置即为需要合并的两个点。

因此只需要支持对于一个树上的单点修改,链上 hash 查询操作,可以直接把树拍成 dfn 序之后用树状数组维护。

时间复杂度 O(mlog2n+nα(n)+nlogV)O(m\log^2n+n\alpha(n)+n\log V)

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

以下称收获一张票为 A,收获一个支持者为 B。

首先考虑在确定了最终哪几个选择 A,哪几个选择 B 时,一定是先按照 bib_i 从小到大依次完成 B,随后以任意顺序完成 A,所需要的时间为 bii+aiB+1\sum\frac{b_i}{i}+\frac{\sum a_i}{|B|+1}。没有很好的贪心选择策略,考虑 dp。

由于 aiB+1\frac{\sum a_i}{|B|+1} 的存在,因此在不确定 B|B| 的前提下,很难对 A 进行 dp,因此首先枚举最终 B 选择了几个。

先按照 bib_i 排序,暴力 dp 为 fi,j,kf_{i,j,k} 表示对于前 ii 个人,当前 B 选了 jj 个,A 选了 kk 个,最小的时间是多少,但是这样时间复杂度为 O(n4)O(n^4),可能可以通过 wqs 二分优化到 O(n3logn)O(n^3\log n)(我没证过),无法通过。

观察一下性质,在对 bib_i 排完序后,如果 ii 选择了 B,那么 <i< i 的位置不可能不选,因为如果位置 jj 不选,那么可以选择 jj 成为 B 而不选 ii,这样不会使结果更劣。

因此可以枚举最后一个选 B 的位置是 ii,那么此时前面已经收获了 ii 张票,后面需要的票数是确定的,直接贪心选择前 kik-i 小的 aja_j 即可。

时间复杂度被优化至 O(n3)O(n^3),可以通过。

ABC219Ex Candles

首先有很显然的性质,由于吹灭蜡烛不需要时间,因此走到一个蜡烛的位置时一定会吹灭这根蜡烛,因此在对 aa 排序后,吹灭的蜡烛一定是一段区间。而没走一步,所有还没有被吹灭的蜡烛的长度都会 1-1

但是如果每走一步都将不在区间内的蜡烛长度 1-1 的话,会出现一些蜡烛的长度被减至负数的情况,导致计算得到的结果更小。

因此考虑对于 dp 状态加一维,表示仍未熄灭的且最终长度 0\ge 0 的蜡烛个数,显然这样不会得到比答案更优的结果。

因此令 fl,r,0/1,if_{l,r,0/1,i} 表示在吹灭的 [l,r][l,r] 区间内的蜡烛后,当前在 0/10/1(左/右 端点),还未被吹灭的会记入最终答案的蜡烛个数为 ii 的最大答案。转移时,枚举这个蜡烛是否被计入最终答案即可。

时间复杂度 O(n3)O(n^3)

P3488 [POI2009] LYZ-Ice Skates

不考虑修改,对于一次询问,建立二分图,左边的每个点表示一个人,右边的每个点表示一双鞋,如果存在一个对于左部点的完美匹配,那么答案为 YES。

根据 Hall 定理,对于左部点的任意一个集合,其对应的右部点的集合大小都应该要大于左部点集合大小。

考虑这张二分图的性质,左部的每个点都对应右部的连续 k(d+1)k(d+1) 个点,因此对于左部点,区间的条件不弱于集合的条件,因此只要对于左部点的每个区间合法即可。

考虑左部点 [l,r][l,r] 的区间,需要满足 i=lraik×(rl+1+d)\sum_{i=l}^r a_i\le k\times (r-l+1+d),将每个 bi=aikb_i=a_i-k,只需要满足 i=lrbik×d\sum_{i=l}^rb_i\le k\times d 即可,因此只需要拿线段树维护 bb 的最大子段和即可。

CF1693C Keshi in Search of AmShZ

不难,但是很有借鉴价值的好题。

考虑题目要求求出最坏情况下的最少时间,因此每次走出边时,考虑走到仍未被删除的最坏的出边。

dud_u 表示从 uu 到终点所需要的最少天数。对于一点 uu,如果没有割掉出边集合 SS,那么 du=max(u,v)Sdv+deguSd_u=\max_{(u,v)\in S}d_v+deg_u-|S|。因此最终保留的边的集合一定是按照 dvd_v 从小到大排序之后的一段前缀。

但是这张图并不是一张 DAG,所以并不能直接求解。考虑在进行 dijkstra 时有性质:当前枚举到的 disdis 一定比之前枚举到的 disdis 大,因此在进行一次 vuv\to u 的更新操作时,选择 dvd_v 作为排序后最后一个选择的没有割边的点,其最短路是 disv+degucntudis_v+deg_u-cnt_u,其中 cntucnt_u 表示已经更新过的 uu 的出边数量。

直接跑 dijkstra 即可,时间复杂度 O(mlogn)O(m\log n),本题巧妙之处在于利用了 dijkstra 过程中的性质来拟合了题目要求的条件。

P6623 [省选联考 2020 A 卷] 树

考虑每一位分别计算。每个点 uu 对他的 kk 级祖先会产生 au+ka_u+k 的贡献,考虑将贡献差分,在每一位的 0/10/1 分界处将差分数组 1\oplus1,但是这样总的差分数组更改量还是 O(n)O(n) 的。

考虑除了第一段,接下来二进制第 ii 位的每一个 0/10/1 连续段的长度都是 2i2^i,因此所有要更改差分的点的深度 mod2i\bmod 2^i 都是相等的,因此直接对于每一个二进制位开一个差分数组,ci,sc_{i,s} 表示二进制后 ii 位为 ss 的点的差分应该要异或多少。

直接在 dfs 的时候维护差分数组即可,复杂度 O(nlogV)O(n\log V),只需要枚举每个二进制位。

另一种解法是直接维护 01trie,需要支持插入元素,合并 01trie,每个数 +1+1 与全局求异或和,可以将 01trie 从低位往高位建,这样全局 +1+1 操作可以通过交换子树来完成,复杂度还是 O(nlogV)O(n\log V)

CF1152F2 Neko Rules the Catniverse (Large Version)

由于限制了每个数只能出现一次,如果按照序列的位置 dp,需要记录每个数是否出现,直接爆炸,因此考虑改变 dp 顺序。

考虑从小到大考虑每一个数 ii,讨论他是否加入序列。

此时如果再记录每个位置是否填了数,那么状态数会飙升至 2k2^k 往上,再乘上 nn 又炸飞了。但是考虑到每个数的具体位置在 dp 过程中并不重要,我们只需要关心每个已经插入的数的相对位置即可,因此可以据此设计 dp 状态。

fi,j,kf_{i,j,k} 表示已经考虑插入了 1i1\sim i 这些数,其中加入序列中的数有 jj 个,最后的四种数是否在序列中出现的状态集合为 kk 的方案数。

由于题目要求对于相邻两个数,后面的数不能大于前面的数 +m+m,因此对于一个数 ii,要么放在序列的开头,要么插在前 mm 个数之后,要么不放,因此转移如下:

{fi,j,kfi+1,j,k×2fi,j,k×(popcount(k)+1)fi+1,j+1,k×2+1\begin{cases} f_{i,j,k}\to f_{i+1,j,k\times 2}\\ f_{i,j,k}\times (\operatorname{popcount}(k)+1)\to f_{i+1,j+1,k\times 2+1} \end{cases}

对于 {j,k}\{j,k\} 一共只有 k×2mk\times 2^m 种,因此可以直接矩阵快速幂优化,时间复杂度 O(k38mlogn)O(k^38^m\log n)

P8688 [蓝桥杯 2019 省 A] 组合数问题

组合数转化成了数位 dp,卢卡斯和进制之间的转化,很新奇。

根据卢卡斯定理,有 (nm)(n/km/k)×(nmodkmmodk)(modk)\binom{n}{m}\equiv \binom{n/k}{m/k}\times \binom{n\bmod k}{m\bmod k}\pmod k,发现这个东西就是将 n,mn,m 写成 kk 进制后对应位组合数的乘积。

题目要求 (xy)0(modk)\binom{x}{y}\equiv 0\pmod k,由于 kk 为质数,因此只要 x,yx,ykk 进制下任意一位的组合数 modk=0\bmod k=0 即可。又由于 x,yx,ykk 进制下的每一位都 <k< k,因此其组合数 =0=0 只有可能是这一位上的 (a,b)(a,b) 满足 a<ba < b

因此可以对 n,mn,m 为上界,在 kk 进制下数位 dp。令 fi,0/1,0/1,0/1f_{i,0/1,0/1,0/1} 表示考虑了 kk 进制的前 ii 位,nn 是否顶到上界,mm 是否顶到上界,是否存在某一位 (a,b)(a,b) 满足 a<ba < b 的方案数。

转移可以直接分类讨论并计算方案数,时间复杂度 O(Tlogkn)O(T\log_k n)

CF1418F Equal Product

考虑对于满足条件的 (x1,y1,x2,y2)(x_1,y_1,x_2,y_2),必有 x1y1=x2y2x_1\cdot y_1=x_2\cdot y_2,因此 x1x2=y2y1=ab\frac{x_1}{x_2}=\frac{y_2}{y_1}=\frac{a}{b},因此 x2=x1ab,y2=y1bax_2=\frac{x_1}{a}\cdot b,y_2=\frac{y_1}{b}\cdot a,并且可以证明 ax1a\mid x_1by1b\mid y_1

通过这个转化,可以发现满足 ax1a\mid x_1(x1,a)(x_1,a) 只有 O(nlogn)O(n\log n) 对,可以直接枚举。

对于一个 x1x_1,我们需要找出一对 (y1,b)(y_1,b) 满足如下条件:

{Lx1y1Rx1x1abny1ma<b\begin{cases} \lceil\frac{L}{x_1}\rceil\le y_1\le\lfloor\frac{R}{x_1}\rfloor\\ \frac{x_1}{a}\cdot b\le n\\ y_1\le m\\ a< b \end{cases}

发现在 x1x_1 递增时,Lx1\lceil\frac{L}{x_1}\rceilRx1\lfloor\frac{R}{x_1}\rfloor 都是单调不增的,因此可以时刻用一个 set 维护满足第一个条件的 (y1,b)(y_1,b) 数对,每次查询时找到最小的满足 b>ab>a 的数对 (y1,b)(y_1,b),判断其是否满足第二个条件即可。时间复杂度 O(nlog2n)O(n\log^2n)

CF1774G Segment Covering

考察对于一对相互包含的区间 [li,ri][lj,rj][l_i,r_i]\subset [l_j,r_j],如果选择了区间 [lj,rj][l_j,r_j],那么多选择一个 [li,ri][l_i,r_i] 也无妨,因此在选择 [lj,rj][l_j,r_j] 的情况下,奇数方案与偶数方案个数相等,可以直接将 [lj,rj][l_j,r_j] 忽略。

现在问题被转化为了一堆左右端点都递增的线段,求恰好覆盖 [L,R][L,R] 的方案数。考虑一次询问怎么做。

fif_{i} 表示选择了 [li,ri][l_i,r_i] 线段,且恰好覆盖了 [L,ri][L,r_i] 这段区间的选偶数个线段的方案 - 选奇数个线段的方案。

初始状态有 f1=1f_1 = -1,转移为 fi=rjlifjf_i=-\sum_{r_j\ge l_i}f_j。模拟几次转移观察有什么性质。
对于第二条线段 [l2,r2][l_2,r_2],如果 l2>r1l_2 > r_1,那么方案数就变为了 00,因为始终无法覆盖中间一段区间,否则 f2=1f_2=1
对于第三条线段 [l3,r3][l_3,r_3],如果 l1l2l3r1l_1\le l_2\le l_3\le r_1,那么有 f3=f2+f1=0f_3=f_2+f_1=0,可以看作 f3f_3 不存在。

同理地,对于接下来的连续一段满足该条件的线段,都有 fi=0f_i=0

直到第一条满足 li>r1l_i>r_1 的线段 ii,如果 li>r2l_i>r_2,那么 fi=0f_i=0,后面的 ff 也全部为 00,否则 fi=f2=1f_i=-f_2=-1
这条线段的下一条线段 i+1i+1 也有 121\to 2 类似的转移方式。由此解决了一组询问的问题。

考虑 pip_i 表示第一条满足 lj>ril_j> r_i 的线段 jj,那么我们维护这两个 ff 值为 1-111 的线段 xxyy,其实是一直在做 x=px,y=pyx=p_x,y=p_y 操作,如果存在两条线段不交那么就无解。

此时观察到一个很妙的性质,如果中途出现了两条线段不交,那么下一步中后面的线段会走到前面的线段位置上,从而使得这两条线段最终重合。而如果不存在线段不交的情况,那么最后两条线段不会重合。

因此将 ipii\to p_i 连边,构成一个内向树的结构,每次询问时倍增跳父亲,答案可以根据最后 x,yx,y 的位置计算得出。

CF1305G Kuroni and Antihype

首先考虑加入一个虚点,点权为 00,初始时 00 在组织中,这样就能保证最终一定存在一种最优状态是所有人都在组织中的。

假设将一个人加入组织时,被邀请的人也能获得收益,那么一对人相互邀请的贡献是确定了,最后只需要减去所有人的收益和(加入组织实际上是没有收益的)即可。

考虑在能相互邀请的人之间连边,边权为 au+ava_u+a_v。原问题等价于求出这棵树的最大生成树。

虽然这棵树的边树可能会很多,但是把相同点权的点缩起来之后,本质不同的边只有 3183^{18} 条。可以从大到小枚举边权,然后枚举两边点,用 kruskal 求解最大生成树即可。时间复杂度 O(n+318α(318))O(n+3^{18}\alpha(3^{18}))

CF1019C Sergey's problem

首先考虑忽略第一个限制,找出一个点集使得从这个点集出发走一步能走到所有点。

对于每个点维护一个标记,表示这个点是否能被当前点集中的至少一个点走一步后到达。依次枚举每个点,如果这个点未被标记,那么将这个点加入点集,并将这个点的所有出边能到达的点进行标记。

不难发现这样构造出的点集能在之多一条边内走到所有点,并且这个点集的导出子图是一个 DAG!

证明考虑记录每一个点被标记的时间戳 tut_u,对于一条边 uvu\to v,如果 u,vu,v 都在点集中,那么一定有 tv<tut_v< t_u,否则在标记 uu 时一定会将 vv 标记。因此对于导出子图中的每一条边 uvu\to v,必有 tu>tvt_u> t_v。因此这张导出子图一定是 DAG。

考虑对 DAG 拓扑排序,也类似第一次构造的形式进行标记,那么最终选择的点集内的点至少一步能走到第一次选出的点集,从而保证了至少两步能够到达所有点,也满足的点集内的点两两之间不变的限制。

CF1553I Stairs

不难发现所有极长的连续自然数按顺序组成的区间互不相交,因此可以根据 aa 数组推断出连续段依次的长度,假设为 bb,长度为 mm

现在的限制是每个连续段内的值连续且递增或递减,且任意相邻的两个连续段的值域都不能相邻(不然就能拼接起来了,不符合条件)。

考虑容斥,假设钦定 ii 对相邻的区间之间的值域是相邻(不合法)的,那么区间被合并为了 mim-i 段,给每一段分配数的方案数是 (mi)!(m-i)!,每一个长度 2\ge 2 的段能选择递增还是递减。

考虑列出 dp 转移方程,设 fi,jf_{i,j} 表示考虑了前 ii 段,现在合并出了 jj 个连续段的方案数。有:

{fi,j=2×k<ifk,j1bi1fi,j=fi1,j1+2×k<i1fk,j1bi=1\begin{cases} f_{i,j}=2\times \sum_{k< i} f_{k,j-1} & b_i\not=1\\ f_{i,j}=f_{i-1,j-1}+2\times \sum_{k< i-1} f_{k,j-1} & b_i=1 \end{cases}

此时,设 fi,f_{i,\dots} 的生成函数为 FiF_iff 的前缀和的生成函数为 GiG_i,那么有转移:

{[Gi1Fi]=[Gi2Fi1]×[12x12x]bi1[Gi1Fi]=[Gi2Fi1]×[12x1x]bi=1\begin{cases} \begin{bmatrix}G_{i-1}&F_i\end{bmatrix}=\begin{bmatrix}G_{i-2}&F_{i-1}\end{bmatrix}\times \begin{bmatrix}1&2x\\1&2x\end{bmatrix} & b_i\not=1\\ \begin{bmatrix}G_{i-1}&F_i\end{bmatrix}=\begin{bmatrix}G_{i-2}&F_{i-1}\end{bmatrix}\times \begin{bmatrix}1&2x\\1&x\end{bmatrix} & b_i=1 \end{cases}

可以直接通过多项式分治乘法求解出最后的 dp 矩阵,再根据最后的 dp 值容易算出答案。复杂度 O(nlog2n)O(n\log^2 n)

P8990 [北大集训 2021] 小明的树

有点诈骗的感觉,但是总体还是不错的一道题。以下称点亮的点为白点,未点亮的点为黑点。

题目的合法性要求是所有的白点的子树内都是白点,因此原树中一定存在一些互不相交的全部为白点的子树。而对于所有的黑点,一定都存在于与 11 联通的连通块内。至此,合法条件被转化为了所有的黑点都在一个连通块内。

由于所有黑点的连通块构成的依旧是树的形态,因此对于森林的连通块个数,我们可以通过点数 - 边数计算,也就是在第 ii 次操作和,合法的条件等价于 nin-i- 连结两个黑色节点的边数 =1=1

再考虑所有合法状态下对答案的贡献,是所有白点的连通块个数,也就是所有连结黑点与白点的边的个数。

至此,树的形态已经不重要了,我们只关心每个操作后每种边的个数。对于一个询问,我们需要求出所有 nin-i- 连结两个黑色节点的边数 =1=1 的时刻的连结两个黑色节点的边数。

由于 nin-i- 连结两个黑色节点的边数 1\ge 1,所以我们可以直接将两个东西看成一个二元组 (a,b)(a,b),询问需要求出 aa 最小的二元组的 bb 之和,可以直接放到线段树上维护,修改时就是区间二元组每个元素的 +/+/- 操作,容易维护。

Powered by Hexo, theme by Facter