IOI2021 集训队作业
A (WF 2014) : A B C E F G H I J K L (HJL)
B (WF 2015) : B E G H J K L M (B)
C (WF 2016) : A B D F H I J K M (HIJ)
D (WF 2017) : A B D G H J K L (AHJ)
E (WF 2018) : C D E G H I J (CEGIJ)
F (WF 2019) : B C F G I J K (BCF)
G (NEERC 2017) : F G H I J K L (FH)
H (NEERC 2016) : B C D G I K L M (I)
I (NEERC 2015) : B C D H I J K L (H)
J (NEERC 2014) : C D E G H I (CD)
K (NEERC 2013) : A C D E G H I K (CEG)
L (CERC 2017) : B C D E I K L (CE)
M (CERC 2016) : B D E G I J L (GI)
N (CERC 2015) : C E F G I J L ()
O (CERC 2014) : A B E G J K L ()
P (CERC 2013) : A D E G H J ()
Q (NEERC,NSub 2017) : C D E F G H J ()
R (NEERC,NSub 2016) : B D E G H I J ()
S (NEERC,NSub 2015) : D F G I K (K)
T (NEERC,NSub 2014) : C E F H K (CH)
U (NEERC,NSub 2013) : C H I J L (L)
目前 AC 数目 : 115
\(\texttt{#209. Intrinsic Interval}\)
简要题意
给一个 \(1-n\) 的排列 \(a_1 a_2 \cdots a_n\) . 定义一个区间为本原连续段当且仅当这个区间排序之后是连续的一段.
有 m 次询问,每次询问一个 \(l_i\) \(r_i\) 查询包含它的最小本原连续段。
\(1\leq n \leq 10^5\) , \(1\leq m \leq 10^5\)
Solution(离线做法)
一个区间合法的条件是 \(max-min=r-l\) , 并且不难证明本原连续段要么包含要么不交。
由于 \(val = max-min-(r-l) \geq 0\)
所以可以在线段树上记 \(val\) 的最小值以及最小值的出现次数 , 这个可以用单调栈 + 线段树 \(\Theta(n\log n)\) 维护。
用一个 \(set\) 记录询问,以 \(l\) 为关键字,在扫描到 \(r\) 的时候在 \(set\) 中加入询问并处理询问即可。
复杂度 \(\Theta((n+m)\log n + m\log m)\) , 需要离线。
有析合树做法,但是还没写。
\(\texttt{#173. Equal Numbers}\)
简要题意
给定一个长度为 \(n\) 的整数数列 \(a_1 a_2 \cdots a_n\) 你可以执行如下操作:选择一个 \(a_i\),并把它乘以任何正整数。
你的任务是对于每个 \(k(0\leq k\leq n)\) 计算:给数列执行 \(k\) 个操作后,数列中包含的数字种类数的最小值。
\(1\leq n \leq 3\times 10^5\) , \(1\leq a_i \leq 10^6\)
Solution
记 \(c_x\) 为 \(x\) 这个数字在数组中的出现次数 .
考虑什么样的操作能使得当前数字种类数减去 \(1\) .
1、找两种不同的数 \(x\) 和 \(y\) , 把 \(x\) 和 \(y\) 合并成一个新的种类 \(z\) , 并且这个种类 \(z\) 可以是任意数 , 需要 \(c_x + c_y\) 次操作 , 操作后 \(c_z = c_x + c_y\) , \(c_x = 0\) , \(c_y = 0\) .
2、找两种不同的数 \(x\) 和 \(y\) , 满足 \(y\) 是 \(x\) 的倍数 , 把 \(x\) 合并到 \(y\) 上去 , 需要 \(c_x\) 次操作 , 操作后 \(c_y += c_x\) , \(c_x = 0\) .
不难发现要么一开始就用了 \(1\) 操作之后一直把其它类别合并到这个 \(1\) 操作产生的 \(z\) 上 (因为 \(z\) 可以是任何数 , 所以令 \(z\) 为 \(1 \cdots 10^6\) 的 \(lcm\) 即可) ,要么是只用操作 \(2\) .
那么这两种方法分别贪心即可。复杂度 \(\Theta(m\ln m + n)\) , 其中 \(m = \max\limits_{i=1}^{n} a_i\)
\(\texttt{#177. Outer space invaders}\)
简要题意
有 \(n\) 个区间 \([a_i,b_i]\) , 每个区间有一个值 \(d_i\) .
你可以在某些位置上放数字(只能放正整数) , 需要保证对于每个 \(i\) 区间 \([a_i,b_i]\) 内都至少有一个位置放了一个 \(\geq v_i\) 的数字 , 最小化放的数字的大小的和。
多组数据 , \(1\leq a_i < b_i \leq 10^4\) , \(1\leq d_i \leq 10^4\) , \(n \leq 300\) , \(\sum n^3 \leq 2.5 \times 10^8\)
Solution
首先对所有 \(a_i\) 和 \(b_i\) 放到一起离散化 , 这样坐标范围就缩小到 \(\Theta(n)\) 级别.
记 \(dp_{l,r}\) 表示被包含在区间 \([l,r]\) 内的所有区间的限制都满足的情况下 , 最小的放的数字的大小之和。
转移的时候枚举这个区间内 \(d_i\) 最大的区间的 \(d_i\) 放在什么位置即可 , 单组数据复杂度 \(\Theta(n^3)\) , 总复杂度 \(\Theta(\sum n^3)\)
\(\texttt{#294. Gangsters in Central City}\)
简要题意
给你一棵 \(n\) 个点的树,树的叶子节点是房屋,树根是供水系统的中心。
有一些点被占据了,你要断掉一些边使得被占据的点到不了树根,并且最小化断边条数,在最小化断边条数的情况下最小化到不了树根的点的个数。
有时候一个点会被占据或者取消被占据状态,有 \(q\) 个操作,每次操作后都要输出答案。
Solution
不难发现,最优方案显然是对于根的每个子树取它的 \(lca\) , 将 \(lca\) 到它父亲的边断掉。
直接维护每个子树内部点的 \(lca\) 即可,复杂度 \(\Theta((n+q)\log n)\)