0%

tea-1219

补档ing

12.19 ABC 272E

https://atcoder.jp/contests/abc272/tasks/abc272_e

输入 n(≤2e5) m(≤2e5) 和长为 n 的整数数组 a (-1e9≤a[i]≤1e9),下标从 1 开始。
执行如下操作 m 次:
对 1~n 的每个 i,把 a[i] += i。
每次操作后,输出 mex(a),即不在 a 中的最小非负整数。


可以知道的一点是mex(a)这个答案的范围一定在$[0,N-1]$之内, 因为假设我们操作很多次之后所有位置上的数字都会变得很大, 由于只有N个数字, 根据鸽笼原理, 至多覆盖从$0$开始的N个位置, 那么如果让最小的那个数字超过了0, 答案就可以取到0, 依次类推, 最终可以发现答案取值是有一个很小的范围的.

那么我们对于每个位置上的数字进行累加次数的讨论, 感兴趣的只有:

  1. 累加L次后, 这个数(如果是负数)刚好大于0了
  2. 累加R次后, 这个数刚好超过(大于等于N)了

那么在$[L,R]$区间内部的累加次数, 这个位置上的数字就处于影响范围内, 需要被考虑; 我们就根据这样的方式按照累加次数进行归类, 每次都来验证一下哪个数字没有出现在$[0,N-1]$的范围内

  • (为什么不会超时?)
  • 第一个数字+1, 累加次数至多N次, 出现N次
  • 第二个数字+2, 累加次数至多N/2次, 出现N/2次
  • … 一直到第N个数字+N, 只会加N/N=1次, 出现1次

$\sum_{i=1}^N \frac{N}{i}$这个级数的模糊上界至少是$N \times log(N)$的, 因此不用担心暴力验证会出现超时的问题(循环内部的执行操作次数最多只有NlogN次).

12.20 ABC 266F

https://atcoder.jp/contests/abc266/tasks/abc266_f

输入 n (3≤n≤2e5) 和 n 条边,点的编号在 [1,n] 内,表示一个没有重边和自环的无向连通图。
然后输入 q(≤2e5) 表示有 q 个询问,每个询问输入两个数 x 和 y (1≤x<y≤n)。
对于每个询问,如果 x 和 y 之间只存在唯一的简单路径,则输出 Yes,否则输出 No。


没写, 等填坑, 基环树

12.21 ABC 275F

https://atcoder.jp/contests/abc275/tasks/abc275_f

输入 $n(\leq 3000) m(\leq 3000)$ 和长为 $n$ 的数组 $a (1\leq a[i] \leq 3000)$。
每次操作你可以删除 $a$ 的一个非空连续子数组。
定义 $f(x)$ 表示使 $sum(a) = x$ 的最小操作次数。
输出 $f(1), f(2), …, f(m)$


构造一个系数数组$b[n]$
那么当我们选取某个$a[i]$的时候, 对应$b[i] = 1$, 否则$b[i] = 0$, 表示不取$a[i]$

考虑$S = \sum_{i=1}^N a[i]b[i] $, 当$S = x, x\in [1, m]$时, 等价于求出了原问题的一种操作方式

定义$f[S][0/1]$表示前?个数字, 取和为$S$, 最后一个数字取or不取的最少操作数.

类似于0-1背包问题, 我们发现:

  • 当前和为S, 这个数不取的情况, 等于之前取+不取(删除, 1次) $f[S][0] = min(f[S][0], f[S][1] + 1)$
  • 当前和为S, 如果这个数可以取 $f[S][1] = min(f[S - x][0], f[S - x][1])$ , 否则$f[S][1] = inf$

最后返回 $S = 1 - M$ 的所有情况解的值即可.

12.22 ABC 273E

https://atcoder.jp/contests/abc273/tasks/abc273_e

一开始你有一个空数组 a 和一个 1e9 页的笔记本,每页上都记录着一个空数组。
有四种类型的操作:
ADD x:在 a 的末尾添加元素 x (1≤x≤1e9)。
DELETE:如果 a 不为空,删除 a 的最后一个元素。
SAVE y:把 a 记在第 y 页上(覆盖原来的数组)。
LOAD z:把 a 替换为第 z 页上的数组。

输入 q(≤5e5) 和 q 个操作。
在每个操作结束后,你需要输出 a 的最后一个元素(数组为空时输出 -1)。

想到前向链表/前缀操作树就很容易实现了(因为我们发现只关心最后一次操作的结果, 之前的数据实际上不需要我们去进行额外的维护, 只要结构可以不断快速的累加, 复制就可以满足条件了)

12.23 ABC 271E

https://atcoder.jp/contests/abc271/tasks/abc271_e

输入 $n,m,k (\leq 2e5)$, 然后输入 $m$ 条边,每条边输入两个点 $x\ y$(表示从 $x$ 到 $y$ 的一条有向边,点的编号 $1-n$ 和一个值在 $[1,1e9]$ 内的边权,每条边的编号 $1-m$

图中没有自环,但可能有重边。

然后输入一个长为 $k$ 的数组 $a (1 \leq e[i] \leq m)$

找到一条从 $1$ 到 $n$ 的路径,满足路径上的边的编号是 $a$ 的子序列

输出满足这个要求的路径的最短长度。如果不存在, 输出 $-1$。


  • 找到一条从 $1$ 到 $n$ 的路径, 满足路径上的边的编号是 $a$ 的子序列: 实际上这个条件还是很强的一个约束(必须按照序列的顺序走, 还需要能够到达最终的终点)
  • 最短长度 => 通过类似于dijkstra的方式放缩这个序列上的所有边, 加边修改距离, 直到序列内所有的边都被放缩使用过, 观察终点的距离值是否可以到达?

类似于这样的放缩:

1
2
3
4
for e in seq:
from, to, w = e
if dis[to] < dif[from] + w:
dis[to] = dis[from] + w