题意:给定长度为 n n n 的 01 01 01 串 s s s,构造一个排序网络,使得能够将除 s s s 之外的任意 01 01 01 序列正确排序,且 s s s 无法被正确排序。 T T T 组测试, 1 ≤ T ≤ 1 0 4 1 \le T \le 10^4 1≤T≤104, 2 ≤ n ≤ 16 2 \le n \le 16 2≤n≤16。
解法:记 01 01 01 串 s s s 中 0 0 0 所在位置的下标集合为 S 0 S_0 S0, 1 1 1 所在位置的下标集合为 S 1 S_1 S1(下标从 1 1 1 开始)。令 S 0 S_0 S0 中最大值为 r r r, S 1 S_1 S1 中最小值为 l l l(显然 l ≤ ∣ S 0 ∣ < r l\le |S_0|
记 t t t 中 0 0 0 所在位置的下标集合为 T 0 T_0 T0, 1 1 1 所在位置的下标集合为 T 1 T_1 T1。上面的算法满足题目要求,证明如下:
题意:平面上给一个 n n n 个点的凸多边形 P 1 P 2 … , P n P_1P_2\dots,P_n P1P2…,Pn,要求找到 3 3 3 个点,使得这三个点构成的三角形的反互补三角形包含所有点(可以在边界上)。 1 ≤ n ≤ 1 0 6 1 \le n \le 10^6 1≤n≤106。
解法:乱搞题,目标是找到一个三角形使得面积极大。有很多不知道对不对但是能过的搞法,一种能证明的做法如下:
在第一步结束后,只有 r r r 能够移动。假设 r r r 逆时针移动,这之后 r , s , t r,s,t r,s,t 就只能逆时针移动,并且 r , s , t r,s,t r,s,t 中任何一个点无法重新移动到 P 1 P_1 P1,因为 S △ P r P s P t S_{\triangle P_rP_sP_t} S△PrPsPt 在移动过程中递增,并且第一步得到的 S △ P 1 P s P t S_{\triangle P_1P_sP_t} S△P1PsPt 已经是最大的。因此时间复杂度不超过 O ( n ) O(n) O(n)。
题意:给一个长为 n n n 的序列,初始状态全为 0 0 0。有两种操作,第一种将区间 [ l , r ] [l,r] [l,r] 内的数均增加 x x x,第二种对区间 [ l , r ] [l,r] [l,r] 内的每个数如果大于或等于 k k k 就减去 k k k( k k k 在所有操作中相等)。你需要执行 m m m 次操作,输出执行完所有操作后所有数一共被减了多少次。 1 ≤ n ≤ 1 0 6 1 \le n \le 10^6 1≤n≤106, 1 ≤ m ≤ 2 × 1 0 5 1 \le m \le 2\times 10^5 1≤m≤2×105, 1 ≤ x , k ≤ 1 0 9 1 \le x,k \le 10^9 1≤x,k≤109。
解法:考虑某个位置上的数。将第 i i i 次操作后的数表示成 a i = c i + k ⋅ b i a_i=c_i+k\cdot b_i ai=ci+k⋅bi 的形式( b 0 = c 0 = 0 b_0=c_0=0 b0=c0=0),其中 b i b_i bi 代表了借位操作次数。考虑如下的一个暴力算法:对于操作一,直接令 c i + 1 = c i + x c_{i+1}= c_i+x ci+1=ci+x。对于操作二,若 a i ≥ k a_i\ge k ai≥k(即 c i + k b i ≥ k ⇒ c i − k ≥ − k b i c_i+kb_i \ge k \Rightarrow c_i-k\ge -k\,b_i ci+kbi≥k⇒ci−k≥−kbi),则令 c i + 1 = c i − k c_{i+1}= c_i-k ci+1=ci−k;否则令 c i + 1 = c i − k c_{i+1}= c_i-k ci+1=ci−k 且 b i + 1 = b i + 1 b_{i+1}= b_i+1 bi+1=bi+1。
引理:使用上述算法计算,所有操作后 b m = ⌈ − min i c i k ⌉ b_m= \left \lceil -\dfrac{\min_{i}c_i}{k}\right\rceil bm=⌈−kminici⌉。
证明:经过一次操作一, c i + 1 ≥ c i c_{i+1} \ge c_i ci+1≥ci,则 min 1 ≤ j ≤ i c j = min 1 ≤ j ≤ i + 1 c j \min_{1 \le j \le i} c_j =\min_{1 \le j \le i+1}c_j min1≤j≤icj=min1≤j≤i+1cj,因而 b i = b i + 1 b_{i}=b_{i+1} bi=bi+1,与上述算法执行过程相同。考虑操作二的两种情况:
- 当 a i ≥ k a_i \ge k ai≥k 时,有 c i + 1 = c i − k ≥ − k b i c_{i+1}=c_i-k \ge -kb_i ci+1=ci−k≥−kbi,因而 b i + 1 = b i ≥ − c i k + 1 ≥ ⌈ − c i k ⌉ b_{i+1}=b_i \ge -\dfrac{c_i}{k}+1 \ge \left \lceil -\dfrac{c_i}{k} \right \rceil bi+1=bi≥−kci+1≥⌈−kci⌉。显然 c i + 1 < c i c_{i+1}
ci+1<ci ,由数学归纳法可得若 b i = ⌈ max 0 ≤ j ≤ i ( − c j ) k ⌉ b_i=\left \lceil \dfrac{\max_{0 \le j \le i} (-c_j)}{k} \right \rceil bi=⌈kmax0≤j≤i(−cj)⌉ 成立则 b i + 1 = ⌈ max 0 ≤ j ≤ i + 1 ( − c j ) k ⌉ b_{i+1}=\left \lceil \dfrac{\max_{0 \le j \le i+1} (-c_j)}{k} \right \rceil bi+1=⌈kmax0≤j≤i+1(−cj)⌉ 成立,即 b i + 1 = ⌈ − min j c j k ⌉ b_{i+1}=\left \lceil -\dfrac{\min_{j}c_j}{k}\right\rceil bi+1=⌈−kminjcj⌉。- 当 a i < k a_i
ai<k 时, 0 ≤ c i + k b i < k 0 \le c_i+kb_i0≤ci+kbi<k 可得 c i ≥ − k b i c_i \ge -kb_i ci≥−kbi。由此时的操作 b i + 1 = b i + 1 b_{i+1}=b_i+1 bi+1=bi+1 可得 c i ≥ − k − k b i + 1 c_i \ge -k-kb_{i+1} ci≥−k−kbi+1,则与第一种情况证明方法相同。
由该引理可知,因此 a i a_i ai 减少的次数一共为 t − b m = t + min i ⌊ c i k ⌋ t-b_m=t+\min_i \left \lfloor \dfrac{c_i}{k} \right\rfloor t−bm=t+mini⌊kci⌋(其中 t t t 为操作二的次数)。
因而本题转化为转化为区间加、单点查询历史最小值,可以参看https://oi-wiki.org/ds/seg-beats/的处理方法,或者使用线段树分治的思想。总时间复杂度 O ( n log m ) O(n\log m) O(nlogm)。
题意:有一个 n × m n\times m n×m 的网格,每格放了块巧克力。Walk Alone(懵哥)和 Kelin 轮流吃巧克力,Kelin 先吃。每轮一个人能选择一个左下角为 ( 1 , 1 ) (1,1) (1,1) 的子矩形,把里面的巧克力吃光,且至少要吃一个。吃到最后一个巧克力的人输。问懵哥和 Kelin 谁赢。 T T T 组测试数据, 1 ≤ T ≤ 1 0 5 1 \le T \le 10^5 1≤T≤105, 1 ≤ n , m ≤ 1 0 9 1 \le n,m \le 10^9 1≤n,m≤109。
解法:当 n = m = 1 n=m=1 n=m=1 显然懵哥赢。当 n > 1 n>1 n>1 或 m > 1 m>1 m>1,假设 Kelin 第一步吃 ( 1 , 1 ) (1,1) (1,1) 并且懵哥赢了,那么 Kelin 可以抢先走懵哥的必胜态且不改变局面(因为 ( 1 , 1 ) (1,1) (1,1) 被任意子矩形包含),因此 Kelin 必胜。
题意:给定一个以 1 1 1 为根的有根树,点个数为 n n n,每个点有点权 a i a_i ai。现要求给每个点重新赋点权 b i b_i bi,且要求 b p i ≤ b i b_{p_i} \le b_i bpi≤bi,其中 p i p_i pi 为 i i i 的父亲。输出最小的 ∑ i = 1 n ( a i − b i ) 2 \displaystyle \sum_{i=1}^n (a_i-b_i)^2 i=1∑n(ai−bi)2。 1 ≤ n ≤ 2 × 1 0 5 1 \le n \le 2\times 10^5 1≤n≤2×105, 0 ≤ a i ≤ 1 0 9 0 \le a_i \le 10^9 0≤ai≤109。
解法:本题主要使用到了 Slope Trick 的方法。
首先我们研究一个简单一些的题目,并从该弱化版的题目中得到本题真正的做法。
弱化版题目:给定一个以 1 1 1 为根的有根树,点个数为 n n n,每个点有点权 a i a_i ai。现要求给每个点重新赋点权 b i b_i bi,且要求 b p i ≤ b i b_{p_i} \le b_i bpi≤bi,其中 p i p_i pi 为 i i i 的父亲。输出最小的 ∑ i = 1 n ∣ a i − b i ∣ \displaystyle \sum_{i=1}^n |a_i-b_i| i=1∑n∣ai−bi∣。 1 ≤ n ≤ 2 × 1 0 5 1 \le n \le 2\times 10^5 1≤n≤2×105, 0 ≤ a i ≤ 1 0 9 0 \le a_i \le 10^9 0≤ai≤109。
用 g u ( x ) g_u(x) gu(x) 表示保证以 u u u 为根的子树满足所有父节点权值小于等于子节点,并且使得 u u u 的权值恰好为 x x x 的最小代价; f u ( x ) f_u(x) fu(x) 表示使得 u u u 的权值至少为 x x x 的最小代价,即 f u ( x ) = min y ≥ x g u ( y ) f_u(x)=\min_{y\ge x} g_u(y) fu(x)=miny≥xgu(y)。可以得到以下转移:
g u ( x ) = ∣ x − a u ∣ + ∑ v ∈ son u f v ( x ) g_u(x)=|x-a_u|+\sum_{v\in \text{son}_u}f_v(x) gu(x)=∣x−au∣+v∈sonu∑fv(x)
首先需要证明引理 1:
f u ( x ) f_u(x) fu(x) 是一个可导且单调递增的函数,且形如 f u ( x ) = c u + ∑ i ∈ S u r ( x − i ) \displaystyle f_u(x)=c_u+\sum_{i\in S_u} r(x-i) fu(x)=cu+i∈Su∑r(x−i),其中:
- r ( x − a u ) = R e L U ( x − a u ) = ( x − a u ) [ x ≥ a u ] r(x-a_u)={\rm ReLU}(x-a_u)=(x-a_u)[x \ge a_u] r(x−au)=ReLU(x−au)=(x−au)[x≥au],其中 [ x ≥ a u ] [x \ge a_u] [x≥au] 为艾弗森括号,表示当 x ≥ a u x \ge a_u x≥au 时值为 1 1 1,反之为 0 0 0。
- S u S_u Su 为 u u u 节点子树中全部 a u a_u au 构成的可重集合。
- c u c_u cu 为一确定常数。
证明:递增性显然成立,下面使用数学归纳法证明该结论。
首先我们考虑叶节点 g u ( x ) g_u(x) gu(x) 与 f u ( x ) f_u(x) fu(x) 的形式—— g u ( x ) = ∣ x − a u ∣ g_u(x)=|x-a_u| gu(x)=∣x−au∣, f u ( x ) = r ( x − a u ) = ( x − a u ) [ x ≥ a u ] f_u(x)=r(x-a_u)=(x-a_u)[x \ge a_u] fu(x)=r(x−au)=(x−au)[x≥au],因而 f u ( x ) f_u(x) fu(x) 是一个单调递增且可导的函数,且符合归纳形式。
注: R e L U {\rm ReLU} ReLU 函数在 x = 0 x=0 x=0 处严格意义上不可导,但是为方便后文的表述,不妨定义 r ′ ( 0 + ) = 1 r'(0^+)=1 r′(0+)=1。对其余非叶节点, g u ( x ) = ∣ x − a u ∣ + ∑ v ∈ son u f v ( x ) \displaystyle g_u(x)=|x-a_u|+\sum_{v\in \text{son}_u}f_v(x) gu(x)=∣x−au∣+v∈sonu∑fv(x)。由可导函数相加还是可导函数, g u ( x ) g_u(x) gu(x) 也同样可导,且 c u + ∑ i ∈ S u r ( x − i ) \displaystyle c_u+\sum_{i\in S_u} r(x-i) cu+i∈Su∑r(x−i) 形式具有可加性。对其做后缀 m i n \rm min min 操作,则 ∣ x − a u ∣ → r ( x − a u ) |x-a_u| \to r(x-a_u) ∣x−au∣→r(x−au),因而 f u ( x ) f_u(x) fu(x) 同样符合原形式。归纳得证。
考虑将 f u ( x ) = c u + ∑ i ∈ S u r ( x − i ) \displaystyle f_u(x)=c_u+\sum_{i\in S_u} r(x-i) fu(x)=cu+i∈Su∑r(x−i) 带入原转移式:
g u ( x ) = ∣ x − a u ∣ + ∑ v ∈ s o n u c v + ∑ v ∈ s o n u ∑ i ∈ S v r ( x − i ) = ( − x + a u + 2 r ( x − a u ) ) + ∑ v ∈ s o n u c v + ∑ v ∈ s o n u ∑ i ∈ S v r ( x − i ) = − x + a u + ∑ v ∈ s o n u c v + ∑ i ∈ S u ′ r ( x − i ) \begin{aligned} g_u(x)&=|x-a_u|+\sum_{v\in{\rm son}_u}c_v+\sum_{v\in{\rm son}_u}\sum_{i\in S_v}r(x-i) \\[3pt] &=(-x+a_u+2r(x-a_u))+\sum_{v\in{\rm son}_u}c_v+\sum_{v\in{\rm son}_u}\sum_{i\in S_v}r(x-i) \\[3pt] &=-x+a_u+\sum_{v\in{\rm son}_u}c_v+\sum_{i\in S_u'}r(x-i) \end{aligned} gu(x)=∣x−au∣+v∈sonu∑cv+v∈sonu∑i∈Sv∑r(x−i)=(−x+au+2r(x−au))+v∈sonu∑cv+v∈sonu∑i∈Sv∑r(x−i)=−x+au+v∈sonu∑cv+i∈Su′∑r(x−i)
其中 S u ′ = ⋃ v ∈ s o n u S v ∪ { a u , a u } S_u'=\bigcup_{v\in{\rm son}_u}S_v\cup\{a_u,a_u\} Su′=⋃v∈sonuSv∪{au,au}。不妨对 g u ( x ) g_u(x) gu(x) 求导,当导函数第一次大于等于 0 0 0 时, x = min S u ′ x=\min S_u' x=minSu′。令 x 0 = min S u ′ x_0=\min S_u' x0=minSu′,当 x = x 0 x=x_0 x=x0 时 g u ( x ) g_u(x) gu(x) 取到最小值 a u − x 0 + ∑ v ∈ s o n u c v \displaystyle a_u-x_0+\sum_{v\in{\rm son}_u}c_v au−x0+v∈sonu∑cv,因此令
S u = S u ′ − { x 0 } c u = a u − x 0 + ∑ v ∈ s o n u c v \begin{aligned} S_u &= S_u'-\{x_0\} \\[3pt] c_u &= a_u-x_0+\sum_{v\in{\rm son}_u}c_v \end{aligned} Sucu=Su′−{x0}=au−x0+v∈sonu∑cv
当 x ≥ x 0 x\ge x_0 x≥x0 时有
f u ( x ) = g u ( x ) = − x + x 0 + c u + ∑ i ∈ S u ′ r ( x − i ) = r ( x − x 0 ) − x + x 0 + c u + ∑ i ∈ S u r ( x − i ) = c u + ∑ i ∈ S u r ( x − i ) \begin{aligned} f_u(x)&=g_u(x) \\[3pt] &=-x+x_0+c_u+\sum_{i\in S_u'}r(x-i) \\[3pt] &=r(x-x_0)-x+x_0+c_u+\sum_{i\in S_u}r(x-i) \\[3pt] &=c_u+\sum_{i\in S_u}r(x-i) \end{aligned} fu(x)=gu(x)=−x+x0+cu+i∈Su′∑r(x−i)=r(x−x0)−x+x0+cu+i∈Su∑r(x−i)=cu+i∈Su∑r(x−i)
当 x < x 0 x
f u ( x ) ≡ c u + ∑ i ∈ S u r ( x − i ) = c u f_u(x)\equiv c_u+\sum_{i\in S_u}r(x-i)=c_u fu(x)≡cu+i∈Su∑r(x−i)=cu
用优先队列维护 S u S_u Su 做启发式合并可以做到 O ( n log 2 n ) O(n\log^2n) O(nlog2n)。
接下来我们回到原问题,即目标函数为平方代价。
用 g u ( x ) g_u(x) gu(x) 表示保证以 u u u 为根的子树满足所有父节点权值小于等于子节点,并且使得 u u u 的权值恰好为 x x x 的最小代价; f u ( x ) f_u(x) fu(x) 表示使得 u u u 的权值至少为 x x x 的最小代价,即 f u ( x ) = min y ≥ x g u ( y ) f_u(x)=\min_{y\ge x} g_u(y) fu(x)=miny≥xgu(y)。可以得到以下转移:
g u ( x ) = ( x − a u ) 2 + ∑ v ∈ son u f v ( x ) g_u(x)=(x-a_u)^2+\sum_{v\in \text{son}_u}f_v(x) gu(x)=(x−au)2+v∈sonu∑fv(x)
用上面同样的方法,可以得到
f u ( x ) = c u + ∑ i ∈ S u ( x − i ) 2 [ x ≥ i ] f_u(x)=c_u+\sum_{i \in S_u}(x-i)^2[x \ge i] fu(x)=cu+i∈Su∑(x−i)2[x≥i]
其中 S u S_u Su 仅为关于 u u u 的集合。这时形式较为复杂,对其做后缀 min \min min 操作难度较大。但是我们可以研究它的导函数以研究它的极小值情况。对转移式两边求导有
g u ′ ( x ) = 2 ( x − a u ) + ∑ v ∈ s o n u f v ′ ( x ) g'_u(x)=2(x-a_u)+\sum_{v\in{\rm son}_u}f'_v(x) gu′(x)=2(x−au)+v∈sonu∑fv′(x)
其中 son u \text{son}_u sonu 表示 u u u 的儿子集合。根据上面同样的方法,显然 f u ( x ) f_u(x) fu(x) 是一个连续、递增、下凸的分段函数,因此 f u ′ ( x ) ≥ 0 f'_u(x)\ge 0 fu′(x)≥0,且由 f u ( x ) = min y ≥ x g u ( y ) f_u(x)=\min_{y\ge x} g_u(y) fu(x)=miny≥xgu(y) 可得
f u ′ ( x ) = max { g u ′ ( x ) , 0 } f'_u(x)=\max\{g'_u(x),0\} fu′(x)=max{gu′(x),0}
用可重集合 S u ⊆ R × N S_u\subseteq\R\times \N Su⊆R×N 维护 f u ′ ( x ) f'_u(x) fu′(x) 的所有拐点以及拐点两侧的斜率差。下用同样的方法证明 f u ′ ( x ) = ∑ ( i , δ ) ∈ S u δ ⋅ R e L U ( x − i ) \displaystyle f'_u(x)=\sum_{(i,\delta)\in S_u} \delta\cdot {\rm ReLU}(x-i) fu′(x)=(i,δ)∈Su∑δ⋅ReLU(x−i)。
证明:同样引入 r ( x ) = x ⋅ [ x > 0 ] r(x)=x\cdot[x>0] r(x)=x⋅[x>0],假设 u u u 的所有儿子节点 f v ′ ( x ) f'_v(x) fv′(x) 都能表示成以下形式:
f v ′ ( x ) = ∑ ( i , δ ) ∈ S v δ ⋅ r ( x − i ) f'_v(x)=\sum_{(i,\delta)\in S_v} \delta\cdot r(x-i) fv′(x)=(i,δ)∈Sv∑δ⋅r(x−i)
代入 g u ′ ( x ) g'_u(x) gu′(x) 的转移式可得
g u ′ ( x ) = 2 ( x − a u ) + ∑ v ∈ s o n u ∑ ( i , δ ) ∈ S v δ ⋅ r ( x − i ) = − 2 a u + 2 x + ∑ ( i , δ ) ∈ S u ′ δ ⋅ r ( x − i ) \begin{aligned} g'_u(x)&= 2(x-a_u)+\sum_{v\in{\rm son}_u}\sum_{(i,\delta)\in S_v}\delta\cdot r(x-i) \\[3pt] &= -2a_u+2x+\sum_{(i,\delta)\in S'_u}\delta\cdot r(x-i) \end{aligned} gu′(x)=2(x−au)+v∈sonu∑(i,δ)∈Sv∑δ⋅r(x−i)=−2au+2x+(i,δ)∈Su′∑δ⋅r(x−i)
其中 S u ′ = ⋃ v ∈ s o n u S v S_u'=\bigcup_{v\in{\rm son}_u}S_v Su′=⋃v∈sonuSv。显然 g u ′ ( x ) g'_u(x) gu′(x) 单调递增,且存在唯一零点 x 0 x_0 x0。考虑由于求后缀 min \min min 使得 x 0 x_0 x0 处增加的拐点 ( x 0 , g u ′ ′ ( x 0 + ) ) (x_0,g''_u(x_0^+)) (x0,gu′′(x0+)),令
S u = { ( i , δ ) ∈ S u ′ ∣ i > x 0 } ∪ ( x 0 , g u ′ ′ ( x 0 + ) ) S_u=\{(i,\delta)\in S'_u\mid i>x_0\}\cup(x_0,g_u''(x_0^+)) Su={(i,δ)∈Su′∣i>x0}∪(x0,gu′′(x0+))
则 f u ′ ( x ) = ∑ ( i , δ ) ∈ S u δ ⋅ r ( x − i ) \displaystyle f'_u(x)=\sum_{(i,\delta)\in S_u} \delta\cdot r(x-i) fu′(x)=(i,δ)∈Su∑δ⋅r(x−i),归纳假设成立。
记 f u ( x ) f_u(x) fu(x) 与 g u ( x ) g_u(x) gu(x) 的最小值为 C u C_u Cu。不难注意到,当子树中存在拐点 ( i , δ ) (i,\delta) (i,δ) 有 i ≤ x 0 i \le x_0 i≤x0 时,由于已经在 x 0 x_0 x0 极其左侧取得最小值,因而 x 0 x_0 x0 左侧的全部拐点都可以删去。在寻找这样的 x 0 x_0 x0 时,可以依次枚举 S u ′ S_u' Su′ 中相邻的拐点,找到零点存在的区间然后求出 x 0 x_0 x0,再删去左侧的拐点。
由于 g ( x ) g(x) g(x) 的极小值在 x 0 x_0 x0 处取到,代入 g u ( x ) g_u(x) gu(x) 的转移式可得
C u = ( x 0 − a u ) 2 + ∑ v ∈ son u f v ( x 0 ) = ( x 0 − a u ) 2 + ∑ v ∈ son u C v + ∑ v ∈ son u ∫ − ∞ x 0 f v ′ ( x ) d x \begin{aligned} C_u&= (x_0-a_u)^2+\sum_{v\in \text{son}_u}f_v(x_0) \\[3pt] &= (x_0-a_u)^2+\sum_{v\in \text{son}_u}C_v+\sum_{v\in \text{son}_u}\int_{-\infty}^{x_0} f'_v(x)\,\text{d}x \end{aligned} Cu=(x0−au)2+v∈sonu∑fv(x0)=(x0−au)2+v∈sonu∑Cv+v∈sonu∑∫−∞x0fv′(x)dx
通过启发式合并可以在 O ( n log 2 n ) O(n\log^2 n) O(nlog2n) 的时间内求出所有集合 S u S_u Su 与每个函数对应的最小值 C u C_u Cu。总时间复杂度 O ( n log 2 n ) O(n\log^2 n) O(nlog2n)。
题意:平面上有 n n n 个圆 C 1 , C 2 , … , C n C_1,C_2,\dots, C_n C1,C2,…,Cn,要求画一个圆 O O O(或直线)经过尽可能多的圆。 1 ≤ n ≤ 150 1 \le n \le 150 1≤n≤150,坐标范围 0 ≤ ∣ x ∣ , ∣ y ∣ ≤ 1 0 3 0 \le |x|,|y| \le 10^3 0≤∣x∣,∣y∣≤103。
解法:当 n ≤ 3 n\le 3 n≤3 时答案为 n n n。当 n > 3 n>3 n>3 时,最优解一定能通过调整使得与至少两个圆外切。枚举 i , j ( i ≠ j ) i,j\ (i\neq j) i,j (i=j),假设圆 O O O 与 C i , C j C_i,C_j Ci,Cj 外切,求 O O O 最多能与多少 C k C_k Ck 相交。
记 C i , C j C_i,C_j Ci,Cj 的半径分别为 r i , r j r_i,r_j ri,rj,圆心分别为 o i , o j o_i,o_j oi,oj(用复数表示)。假设对复平面进行反演映射 f ( z ) = 1 / ( z − o ) f(z)=1/(z-o) f(z)=1/(z−o),则反演后 C i C_i Ci 的圆心和半径分别变为
o i ′ = 1 2 ( 1 o i − r i e − o + 1 o i + r i e − o ) = o i − o ( o i − o ) 2 − ( r i e ) 2 r i ′ = 1 2 ∣ 1 o i − r i e − o − 1 o i + r i e − o ∣ = r i ( o i − o ) 2 − ( r i e ) 2 \begin{aligned} o_i'&=\frac{1}{2}\Big(\frac{1}{o_i-r_ie-o}+\frac{1}{o_i+r_ie-o}\Big) \\ &=\frac{o_i-o}{(o_i-o)^2-(r_ie)^2} \\[6pt] r_i'&=\frac{1}{2}\bigg|\frac{1}{o_i-r_ie-o}-\frac{1}{o_i+r_ie-o}\bigg| \\ &=\frac{r_i}{(o_i-o)^2-(r_ie)^2} \\ \end{aligned} oi′ri′=21(oi−rie−o1+oi+rie−o1)=(oi−o)2−(rie)2oi−o=21 oi−rie−o1−oi+rie−o1 =(oi−o)2−(rie)2ri
其中 e = ( o i − o ) / ∣ o i − o ∣ e=(o_i-o)/|o_i-o| e=(oi−o)/∣oi−o∣。类似地可以计算 C j C_j Cj 的圆心和半径。令反演后 C i ′ C_i' Ci′ 与 C j ′ C_j' Cj′ 圆心位置相同,可以得到
o i − o ( o i − o ) 2 − ( r i e ) 2 = o j − o ( o j − o ) 2 − ( r j e ) 2 \frac{o_i-o}{(o_i-o)^2-(r_ie)^2}=\frac{o_j-o}{(o_j-o)^2-(r_je)^2} (oi−o)2−(rie)2oi−o=(oj−o)2−(rje)2oj−o
解得 A o 2 + B o + C = 0 Ao^2+Bo+C=0 Ao2+Bo+C=0,其中
A = o i − o j B = ( r i 2 − r j 2 ) e 2 − ( o i 2 − o j 2 ) C = ( o i r j 2 − o j r i 2 ) e 2 + o i o j ( o i − o j ) \begin{aligned} A&= o_i-o_j \\ B&= (r_i^2-r_j^2)\,e^2-(o_i^2-o_j^2) \\ C&= (o_ir_j^2-o_jr_i^2)\,e^2+o_io_j(o_i-o_j) \end{aligned} ABC=oi−oj=(ri2−rj2)e2−(oi2−oj2)=(oirj2−ojri2)e2+oioj(oi−oj)
取圆 C i C_i Ci 内部的点 o o o,则反演后除 C i , C j C_i,C_j Ci,Cj 外的所有圆都在 C i C_i Ci 内部、 C j C_j Cj 外部,且 O O O 与 C i C_i Ci 内切,与 C j C_j Cj 外切。对于每个圆 C k C_k Ck,可以计算出 O O O 与 C k C_k Ck 相交时 C i O C_iO CiO 的辐角取值区间,通过扫描线可以求出最多相交的圆的数量。总复杂度 O ( n 3 log n ) O(n^3\log n) O(n3logn)。
题意:给出一种对 n n n 个点的二叉树有根树(树根在 1 1 1)的操作:
问进行 k k k 次操作后有多少棵树能变成给定的树。 1 ≤ n ≤ 1 0 5 1 \le n \le 10^5 1≤n≤105, 0 ≤ k ≤ 1 0 5 0 \le k \le 10^5 0≤k≤105。
解法:注意到每次操作后树的前序遍历不变,因此可以用前序遍历对所有点重新标号。这样标号后点 u u u 的左儿子 ℓ u \ell_u ℓu 满足 ℓ u = u + 1 \ell_u=u+1 ℓu=u+1,且每次操作后边 ( u , r u ) (u,r_u) (u,ru) 会变为 ( min { u + 1 , r u − 1 } , r u ) (\min\{u+1,r_u-1\},r_u) (min{u+1,ru−1},ru)—— u + 1 u+1 u+1 对应第一个操作, r u − 1 r_u-1 ru−1 对应第二个操作(若执行第二个操作此时满足 r u − 1 = u r_u-1=u ru−1=u)。 k k k 次操作后变为 ( min { u + k , r u − 1 } , r u ) (\min\{u+k,r_u-1\},r_u) (min{u+k,ru−1},ru)。
考虑 k k k 次操作后的树最开始的样子。考虑两种边:
于是这道题等价于:一个长度为 n n n 的线段中给定一些长度大于 k k k 的区间,要求在其中添加一些长度不超过 k k k 的区间,使得所有区间互不相交,问一共有多少种方案。
显然新添加的区间不可能跨过给定的区间,因此可以认为这些给定的区间把整个线段划分为了若干段,单独考虑每一段的贡献。令 f i f_i fi 表示长度为 i i i 的区间的方案数,其中 f 0 = f 1 = 1 f_0=f_1=1 f0=f1=1。对于 i ≥ 2 i\ge 2 i≥2 有
f i = f i − 1 + ∑ l = 2 min { k + 1 , i } f i − l ⋅ f l − 2 f_i=f_{i-1}+\sum_{l=2}^{\min\{k+1,i\}}f_{i-l}\cdot f_{l-2} fi=fi−1+l=2∑min{k+1,i}fi−l⋅fl−2
令 g = ∑ i = 0 k + 1 f i x i \displaystyle g=\sum_{i=0}^{k+1}f_ix^i g=i=0∑k+1fixi。当 i ≤ k + 1 i\le k+1 i≤k+1 时 g g g 有生成函数等式:
g = x g + x 2 g 2 + 1 g=xg+x^2g^2+1 g=xg+x2g2+1
解得
g = 1 − x − 1 − 2 x − 3 x 2 2 x 2 g=\frac{1-x-\sqrt{1-2x-3x^2}}{2x^2} g=2x21−x−1−2x−3x2
此时通过多项式求逆求出 f f f 数组的前 k + 1 k+1 k+1 项,即得到了递推的系数项。考虑对于 i > k + 1 i>k+1 i>k+1 时递推式可化简为 f i = f i − 1 + ∑ l = 2 k + 1 f i − l ⋅ f l − 2 \displaystyle f_i=f_{i-1}+\sum_{l=2}^{k+1}f_{i-l}\cdot f_{l-2} fi=fi−1+l=2∑k+1fi−l⋅fl−2,转写成多项式形式为:
f = f x + f g x 2 + 1 f=fx+fgx^2+1\\ f=fx+fgx2+1
即 f = 1 1 − x − g x 2 f=\dfrac{1}{1-x-gx^2} f=1−x−gx21。可以用多项式求逆和多项式开方在 O ( n log n ) O(n\log n) O(nlogn) 时间内求解。
题意:给定两个长度为 n n n 的序列 { a } i = 1 n \{a\}_{i=1}^n {a}i=1n 和 { b } i = 1 n \{b\}_{i=1}^n {b}i=1n,现在可以选择其中一个序列交换其中的两个数字,问经过至多一次操作后最小的 ∑ i = 1 n ∣ a i − b i ∣ \displaystyle \sum_{i=1}^n |a_i-b_i| i=1∑n∣ai−bi∣。 1 ≤ n ≤ 2 × 1 0 5 1 \le n \le 2\times 10^5 1≤n≤2×105, 0 ≤ ∣ a i ∣ , ∣ b i ∣ ≤ 1 0 12 0 \le |a_i|, |b_i| \le 10^{12} 0≤∣ai∣,∣bi∣≤1012。
解法:考虑交换 a i , a j a_i,a_j ai,aj ,不妨设 a i < a j a_i
下面使用一张图来给出最大化 Δ \Delta Δ 的条件。首先定义:
不难注意到:
即将反序相交、反序包络进行交换即可。
不难注意到,我们经过一次交换不同种类(正序和反序)的区间,可以消除两倍的重叠(包络)长度。
具体到做法,首先考虑将所有区间一起按右端点( max ( a i , b i ) \max(a_i,b_i) max(ai,bi))排序,按右端点递减的顺序依次枚举每个区间。假设当前枚举的区间满足 a i < b i a_i
最后答案即为原始答案减去二倍的最大重叠区间长度。总时间复杂度为 O ( n log n + n ) \mathcal O(n \log n+n) O(nlogn+n)。