做题集合

T1.P10136

神秘人类智慧题。

如果离散化后的 n3,那么答案即为 mx×(mx+1)2。接下来考虑 n4 的情况。

应为鸽巢原理当 aimodL 只有三种不同的取值,所以必定有两个数 i,j 满足条件 aiaj(modL) 并且 1i<j4。那么就可以推出 L(aiaj)

那么我们只需要枚举所有满足条件 1i<j4i,j,然后查看 aiaj 的所有因数当中所有符合条件的数的和即可。

T2.P4156

我们先求出所有 |s|border 的长度,记为 {xi},那么题目要求的就是 i=1cntai×xi 能在 [0,w|s|] 中取到多少种值。

注意到这个形式是同余最短路的形式,所以我们考虑使用同余最短路来解决。但是直接做是 O(n2logn) 的,不可以通过。

此时抛出一个定理:一个字符串排序之后,必定有一种划分序列的方式,使得所有的序列均为等差序列,且序列个数为 O(log|s|)

那么根据 border 这个优美的性质,我们考虑把 x,x+d,x+2dx+l×d 这个等差数列在 modx 的意义下跑同余最短路。其中 y 连向 (y+d)modx。那么会形成 gcd(x,d) 个环,每一个环分开处理。

我们发现一个环中 dis 最小的点是不会更新的。并且两边的点的 dis 均等于 d。那么我们就从这个点出发用单调队列结算 dis。我们在单调队列里放入离现在处理点距离小于等于 l 的点,以 disiposi×d 作为比较,这样我们就能处理环上的转移。

那么剩下的为题就是怎么两个不模数的转移。假设现在的模数为 now,之前的为 lst,那么很明显 disi 可以更新 disdisimodnow。然后根据定义我们只需要在 modnow 的意义下跑一遍同余最短路并且使用用 x 更新 (x+lst)modnow 即可。

时间复杂度为 O(nlogn)

T3.P9197

考虑连续段 dp。

我们把 ai 从大到小后排序然后依次插入。

此时我们设计 dpi,j,k,s 表示目前考虑了 i 个数。有 j 个连续段,目前答案为 k,首尾都没取/只取了其中之一/两个都取了。答案就是 i=0ldpn,1,i,2

转移就很简单了:

  1. 作为首尾,开新段:相邻一个数,但是没有填,价值为 Ai

  2. 作为首尾,接着另一个段:相邻与个数,填了,价值为 Ai

  3. 不作为首尾,开新段:相邻两个数,但是都没有填,价值为 2×Ai

  4. 不作为首尾,连接两个段:相邻两个数,都填了,价值为 2×Ai

  5. 作为首尾,接在一个段的后面:相邻两个数,一个没有填,一个填了,价值为 0

然后直接转移即可。

T4.AT_agc001_e

首先我们知道 (ai+bi+aj+bjai+aj) 等价于从 (0,0) 到点 (ai+bi,aj+bj) 的方案数。

但是这样子还是不能解决,应为我们还是要枚举终点才能知道。

此时我们考虑变为从 (ai,bi)(aj,bj) 的路径数量。

那么这样就只会有 n 个起点和 n 个终点。

此时我们定义 dpi,j 表示丛所有的起点走,有多少种路径可以到达 (i,j)

那么答案即为 i=1ndpai,bii=1(2×(ai+bi)2×ai)2

当然为了防止负数溢出,所有的坐标 (x,y) 都变为 (x+2000,y+2000)

T5.AT_agc043_d

好玩的。

假如这个序列为 {3,2,1} 状物,那么当第一个数被选出后,后面两个数立刻会被选出。

这样我们可以把下降的一段用第一个数字代替。这样这个操作就是正常的排序了。

那么一个长度为 3 的序列就可能贡献:

  • 一个长度为 3 的下降子序列。

  • 一个长度为 2 和一个长度为 1 的下降子序列。

  • 三个长度为 1 的下降子序列。

那么我们此时设计 dp,其中 dpi,j 表示目前考虑到第 i 个数,长度为 1 的字段数量比长度为 2 的字段数量多 j。然后转移 dp 即可。

T6.AT_arc070_c

Slope Trick!

先有个朴素的 dp:我们定义 dpi,j 表示把第 i 个方块移到 j 这个位置上的最小代价。那么转移方程就是:

dpi,j=|jli|+minjleni1kj+lenidpi1,k

然后因为 |jli| 为凸函数,然后我们发现 dpi, 为凸函数。然后我们考虑用队列来维护这个凸包的每一个转折点。

具体的,我们维护斜率大于 0 和斜率小于 0 的部分的转折点,同时答案必定会在斜率等于 0 时取到。

T7.神秘

我们考虑定义 dpi 表示前 i 个数能表示出的不同序列的数量。

那么就有:

dpi=dpj×gi,j

其中 gi,j 表示区间 [j,i] 能表示出区间 [j,i1] 有多少个不能表示出的序列。

假若我们可以将 ai 插入 [j,i1] 的线性基当中,那么 gi,j=2p,否则为 0,其中 p 为线性基的大小。

T8.AT_abc236_f

基本不会线性基了,做几道练练手。

既然要代价最小,那么先将代价从小到大排序。排完序后,我们将下标插入线性基,如果可以插入,那么就加上这个下标对应的代价,否则跳过。

T9.神秘2

我们发现如果维护每一个点肯定是不现实的。

但是我们发现同一层的点的情况是相同的。一就是说一个点跟深度有关,和位置无关。然后我们发现有区间操作,于是考虑用线段树来维护。

然后我们发现一个点 x 肯定是先向祖先走若干步,然后再儿子走若干步。那么我们就可以维护这个点向祖先走的步数,以及向儿子走的步数与方向,然后再把两条路径合并即可。

T10. P7470 [NOI Online 2021 提高组] 岛屿探险

我们可以发现这个东西可以拆成很多个子问题,然后累计合并,这个东西可以使用线段树合并来做。

先考虑 bi>dj 的情况。那么答案就是 [aicjdj]。我们把 ai 插入 01trie 中。然后我们从上往下走,走到深度为 h 的节点,那么代表他的值等于 cidj 的前 h 位。然后我们考虑第 h+1 位。

  • di=0,那么 aicj 的第 h+1 位必须相等,否则 aicj>dj,然后直接往这个方向走即可。

  • di=1,那么此时 aicj 的第 h+1 位任意取都行。那么就有两种可能:

    • 如果 aicj 的第 h+1 位不一样,那么此时 ai 依然等于 cjdj,所以我们向这个方向继续走即可。
    • 如果 aicj 的第 h+1 位一样,那么此时 aicj 就会一定小于 dj 了,那么对于答案的贡献就是这个子树里 ai 的个数之和。

这一部分就是 CF817E。比较简单。

接下来我们考虑 bidj 的情况。这一个部分比较困难。但是我们发现这一个部分和 aicjdj 的结构很像,所以我们可以考虑类似的操作。

前面的是对于 ai 扔到 01trie 上然后查询 (cj,dj),那么我们这次就可以把 cj 扔到 01trie 上,然后记录每一个 (ai,bi) 对于 cj 的贡献。

具体的我们只需要把 cj 离线下来,然后对于 (ai,bi) 查询,但是唯一的区别就是在上面我们遇到了一个节点满足 aicj<dj 时我们加上的是子树里 ai 的个数和,而现在我们要在这一个子树打一个标记,让整一个子树全部都加上 1,然后统计答案是就是从根到 cj 路径上的标记和。

当然我们不能每一次都建 201trie,但是那样子的复杂度爆炸,无法接受。

然后我们考虑如何优雅的计算多组数据。

首先我们将 (ai,bi)(cj,dj) 按照 bi,dj 升序排列。然后那双指针进行维护。此时我们开两个 01trie。然后当我们扫到了第 j 个问题不满足 bj>djai 从维护第一个 01trie 中删除,然后计算贡献。同时对于满足条件的 (ai,bi) 加入维护第二个情况的 01trie 上并且计算贡献。

当然此时两个指针都往右移动。

T11.The Third Grace

*3200。首先你需要知道 KTT,不会的话请做 P5693。

考虑 dp。我们定义 dpi 为我们最后一个激活的点为 i 的最大权值,但是其中不包括 i 的贡献。

应为我们不会算当前点的贡献,所以我们可以增加一个虚点 m+1,那么答案就是 dpm+1

然后我们考虑如何转移。

我们枚举下一个激活的点的位置。因为我们现在加的是 i 对于答案的贡献,那么 dpj=max(dpj,dpi+l=1nr=1n[lir<j]×pi)

然后扫描线一下,对于所有的 x 维护所有 y 的贡献,最后取 max 即可。

接着我们发现贡献的式子是一个一次函数 yi=kixi+bi。那么我们需要维护三种操作:

  • 全局求 max(yi)

  • 对于一个区间 [l,r],让里面的所有 xi 都加上 1

  • 单点修改 bi

我们用 KTT 来维护这些一次函数,时间复杂度为 O(mlog3m)

T12.P10120

老大过得还好吗?

我们定义 Ai 为最后连续喝了多少瓶原味冰红茶,Bi 为最后连续喝了多少瓶热带风味冰红茶。

然后我们就发现第一个操作就等价于:

i[l,r]AiAi+k,Bi0

i[1,l1]Ai0,BiBi+k

i[r+1,n]Ai0,BiBi+k

那么对于这个操作,我们只需要维护一颗线段树,支持区间推平和区间加即可。

接下来考虑第二个操作,我们考虑到哪一种节点就不用往下搜了。

这是简单的:只要这个子树里面 maxAimaxBi 都小于 k 即可。

剩下的就正常做即可。

T13.AT_agc023_f

应为删点不好做,所以我们套路的变为合并。那么这题就变为:最初有 n 个孤立点,然后每一次和他的父亲合并。那么在合并的过程中,同一个连通块内部的最少贡献是不变的。我们所要做的事情是合理地安排它们的顺序,使不同连通块之间的产生贡献最小。

假设点 u 所在的集合中,0 点的数量为 cntu,01 点的数量为 cntu,1,点 v 同类。那么 u 排在 v 前面,跨越联通块的贡献为 cntu,1×cntv,0。那么我们把 u 放在 v 前面更优的方案的判定就是 cntu,1×cntv,0<cntu,0×cntv,1

所以我们按照 cntu,1cntu,0 的大小来排序即可。

T14.CF1936B

有趣的题目。

先考虑 i 位置的小球会在哪一个边出。很明显,如果 j=1i[sj==>] 大于 j=i+1n[sj==<] 那么就会从右边出去,反之从左边出。此时我们考虑最优答案怎么算。

在此我们以 si 为 <,并且最后从做左出的情况为例,而其余的情况相同。

我们记 lki 左侧第 k 个满足条件 1ji 并且 sj==>jrk 同理。很明显,我们的路线应该是先走到 l1,然后走到 r1,然后再走到 l2,然后再走到 r2,这样子一直走下去。

那么总路程就是 |il1|+|l1r1|+|r1l2|++rcnt=2×cnti=1ri2×cnti=1li+i

cnt 的求法是平凡的,我们只需要用前缀和即可。

T15.P9200

考虑暴力枚举 n+1 在哪一个位置后面,然后每一次考虑维护答案。

此时我们记 sumi=j=1iej。那么对于从一个起点 i 移动到终点 j 的电荷量就是 sumjsumi1

那么我们要求的答案就是 j=1n+1|sumjsumi1|×cj。其中 i 为粒子环游的开始节点。由于 sumn+1=sum0=0,所以这个式子就等价于 j=1n+1|sumjsumi|×cj。那么现在我们考虑这个式子在什么时候取到最最小值。

但是我们发现直接处理绝对值是一件很难的事情,所以我们考虑用几何意义吧绝对值拆开来。那么上面那个式子的几何意义就是在数轴上有 n+1 个点,点有点权,现在需要选取一个点,使得所有点到这个中心点的加权距离和最小。但是我们发现带权也不好做,所以考虑把一个点拆成 ci 个点,那么总点数就变为了 ci,并且不带权。

那么我们只需要选出来这 ci 个点的中心点就行了。即点按照坐标大小排序后的第 ci2 个数,然后这个东西用权值线段树维护即可。

T16.P6947

前置知识:Voronoi 图

  1. Voronoi 图把平面划分成 n 个多边形域,每个多边形内只有一个生成元
  2. 每个多边形内的点到该生成元距离短于到其它生成元距离
  3. 多边形边界上的点到生成此边界的两个生成元的距离相等

接下来考虑如何得到一个 Voronoi 图。

这是十分显然的,我们只需要求出一个点和其余点的中垂线半平面的交。

这个过程需要求 n 次半平面交,所以时间复杂度为 O(n2logn)

首先一个半径 r 能成为答案的条件就是对于所有的 AP,均有 min{|AP1|,|AP2|,|APn|}r

很明显,我们最终的答案就是 maxAPmin{|AP1|,|AP2|,|APn|}

此时我们钦定 |APi|=min{|AP1|,|AP2|,|APn|},则这样的 A 的范围是关于 P1,P2Pn 的 Voronoi 图 Pi 所在的区域中。此时我们考虑他所在的区域和 P 的交集,很明显这也必定是一个多边形,我们令他为 Q

所以我们只需要找到里 Pi 最远并且在 Q 上的点。通过直观感受,我们发现这个点是 Q 的一个顶点

接下来我们可以对 Q 的顶点分一个类:

  1. 某个 Pi

  2. Voronoi 图的某个多边形的顶点

  3. Voronoi 图和 P 的交点

那么此时我们直接用 O(n2logn) 的方法建出 Voronoi 图,然后考虑那三种点的贡献:

  1. 0

  2. 对于 Voronoi 图的顶点最多有 O(n) 个,所以我们只需要用 O(n) 的时间判断点是否在多边形内部,然后统计答案即可。时间复杂度 O(n)

  3. 这样的点显然在多边形内部 (含边上),直接更新即可。时间复杂度 O(n)

最终时间复杂度为 O(n2logn)

posted @   sqrtqwq  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示