记录近期训练遇到的一些值得记录的题。
CF1972D2
题意
给定 n , m ( 1 ≤ n , m ≤ 2 ⋅ 1 0 6 ) n,m(1\le n,m\le2\cdot 10^6) n,m(1≤n,m≤2⋅106),求满足 1 ≤ a ≤ n , 1 ≤ b ≤ m 1\le a\le n,1\le b\le m 1≤a≤n,1≤b≤m 且 b ⋅ gcd ( a , b ) b\cdot \gcd(a,b) b⋅gcd(a,b) 是 a + b a+b a+b 的倍数的有序对 ( a , b ) (a,b) (a,b) 的个数。
做法
- 记 g = gcd ( a , b ) g=\gcd(a,b) g=gcd(a,b)。由于 b g bg bg 和 a + b a+b a+b 都是 g g g 的倍数,尝试把 g g g 约去,得 b = y g b=yg b=yg 是 x + y x+y x+y 的倍数,其中 a = x g , b = y g a=xg,b=yg a=xg,b=yg
- 此处还有一个容易忽略的重要性质,即 gcd ( x , y ) = 1 \gcd(x,y)=1 gcd(x,y)=1,进而有 gcd ( x + y , y ) = 1 \gcd(x+y,y)=1 gcd(x+y,y)=1。也就是说, y y y 中不含 x + y x+y x+y 的质因子,可以从式子中移除,得到 g g g 是 x + y x+y x+y 的倍数
- 由于 x + y < g x+y<g x+y<g 且 x g ≤ n , y g ≤ m xg\le n,yg\le m xg≤n,yg≤m,可以发现无论是 g g g 较小时还是 g g g 较大时, x + y x+y x+y 都较小。因此尝试先枚举 g g g 再枚举 x + y x+y x+y 再枚举 x x x,发现枚举次数较小,刚好能卡过
CF1972E
题意
给定长度为 n ( n ≤ 2 ⋅ 1 0 5 ) n(n\le 2\cdot 10^5) n(n≤2⋅105) 的数组 b b b 和正整数 k ( k ≤ 1 0 9 ) k(k\le 10^9) k(k≤109),求一个数组 a a a,使得 b = f k ( a ) mod 998244353 b=f^k(a)\text{ mod }998244353 b=fk(a) mod 998244353,其中 f ( a ) f(a) f(a) 表示对 a a a 建的树状数组, f k ( a ) f^k(a) fk(a) 表示嵌套 k k k 层操作。
做法
- 在建立树状数组的过程中,在对应的树上,每个结点都会贡献给它的全体祖先
- k k k 次操作后,每个结点对其父结点的贡献次数为 k k k,对其 2 2 2 阶祖先的贡献次数为 ∑ i = 1 k i \sum_{i=1}^{k}i ∑i=1ki,对其 3 3 3 阶祖先的贡献次数为 ∑ i = 1 k ∑ j = 1 i i \sum_{i=1}^{k}\sum_{j=1}^{i}i ∑i=1k∑j=1ii。据此类推,对其 b b b 阶祖先的贡献次数为一个长度为 k k k 的数组求 b b b 次前缀和后的末元素大小。这个问题相当于一个 k × ( b + 1 ) k\times (b+1) k×(b+1) 的格路问题模型,结果为 C ( k + ( b + 1 ) − 2 , k − 1 ) = C ( k + b − 1 , b ) C(k+(b+1)-2,k-1)=C(k+b-1,b) C(k+(b+1)−2,k−1)=C(k+b−1,b)
- 按照 lowbit 从小到大的顺序使每个位置删去贡献即得 a a a
CF1916E
题意
给定一棵大小为 n ( n ≤ 3 ⋅ 1 0 5 ) n(n\le 3\cdot 10^5) n(n≤3⋅105) 的有根树以及每个结点的颜色 a ( a i ∈ [ 1 , n ] ) a(a_i\in[1,n]) a(ai∈[1,n]),求一对结点 ( u , v ) (u,v) (u,v) 使得 d i f f ( u , l c a ( u , v ) ) ⋅ d i f f ( v , l c a ( u , v ) ) diff(u,lca(u,v))\cdot diff(v,lca(u,v)) diff(u,lca(u,v))⋅diff(v,lca(u,v)) 最大。其中 d i f f diff diff 代表两个结点间路径上的颜色种数, u , v u,v u,v 可以相同。
做法
- 枚举 lca,当 x x x 作 lca 时找到 x x x 所有子结点子树中最优的链,选择其中最优的两条链相乘来更新答案。剩下的关键问题是如何快速求出以某结点为根的最优链
- 考虑在 DFS 回溯的过程中维护当前结点子树中所有结点到当前结点的链的答案,其实只需要在回溯过程中不断将重复颜色的贡献删去即可。当回溯到结点 x x x 时,需要加上 x x x 的贡献,其作用于 x x x 的子树;同时需要删去 x x x 下方距其最近的同色结点 { y } \{y\} {y} 的贡献,这些贡献作用于 y i y_i yi 的子树。为了方便对子树信息进行修改,可以使用欧拉序将树映射到序列,再用线段树维护序列上每个结点到当前结点的链答案。
GYM105139K
题意
给定数轴上的 n ( n ≤ 1 0 6 ) n(n\le 10^6) n(n≤106) 个一维坐标 a ( 0 ≤ a i < 998244353 ) a(0\le a_i<998244353) a(0≤ai<998244353),每次随机选择两个相邻的坐标,将它们用它们的平均值替换,直到只剩一个值。求最终值的数学期望。
做法
- 分别计算每个数的贡献系数,假设某个数当前左边有 x x x 个数,右边有 y y y 个数,其贡献系数记为 f i , j f_{i,j} fi,j。根据是否选中该数以及选中该数的左边还是右边分四类情况讨论,得 f i , j = i − 1 i + j f i − 1 , j + 1 i + j 1 2 f i − 1 , j + j − 1 i + j f i , j − 1 + 1 i + j 1 2 f i , j − 1 = 1 i + j ( ( i − 1 2 ) f i − 1 , j + ( j − 1 2 ) f i , j − 1 ) f_{i,j}=\frac{i-1}{i+j}f_{i-1,j}+\frac{1}{i+j}\frac{1}{2}f_{i-1,j}+\frac{j-1}{i+j}f_{i,j-1}+\frac{1}{i+j}\frac{1}{2}f_{i,j-1}=\frac{1}{i+j}((i-\frac{1}{2})f_{i-1,j}+(j-\frac{1}{2})f_{i,j-1}) fi,j=i+ji−1fi−1,j+i+j121fi−1,j+i+jj−1fi,j−1+i+j121fi,j−1=i+j1((i−21)fi−1,j+(j−21)fi,j−1)
- 令 g i , j = ( i + j ) ! f i , j g_{i,j}=(i+j)!f_{i,j} gi,j=(i+j)!fi,j,则 g i , j = ( i − 1 2 ) g i − 1 , j + ( j − 1 2 ) g i , j − 1 g_{i,j}=(i-\frac{1}{2})g_{i-1,j}+(j-\frac{1}{2})g_{i,j-1} gi,j=(i−21)gi−1,j+(j−21)gi,j−1 恰好是一个网格图路径计数问题的答案,可以用组合数计算
- 最终答案为 ∑ i = 0 i = n − 1 f i , n − 1 − i \sum_{i=0}^{i=n-1}f_{i,n-1-i} ∑i=0i=n−1fi,n−1−i
GYM105158D
题意
给定 n ( n ≤ 2 × 1 0 5 ) n(n\le 2\times 10^5) n(n≤2×105) 个二维点坐标,求所有点对中曼哈顿距离比欧几里得距离 ∥ P i P j ∥ 1 ∥ P i P j ∥ 2 \frac{\lVert P_iP_j\rVert _1}{\lVert P_iP_j\rVert _2} ∥PiPj∥2∥PiPj∥1 的最大值
做法
- 分析式子得:所求即为连线角度最接近 4 5 ∘ 45^\circ 45∘ 或 13 5 ∘ 135^\circ 135∘ 的点对
- 关键结论:分别按照 x + y x+y x+y 和 x − y x-y x−y 排序,最优点对一定在其中一个排序下是相邻的。证明可以考虑任意三个点连成的三角形,其中最上方和最下方的点的连线一定不会是三角形中最接近水平的。
GYM105143D
题意
给定长度为 n ( n ≤ 5000 ) n(n\le 5000) n(n≤5000) 的数组 a a a,求 F i , j ( 1 ≤ i ≤ n , 1 ≤ j ≤ 2 n ) F_{i,j}(1\le i\le n,1\le j\le 2n) Fi,j(1≤i≤n,1≤j≤2n),其中 F i , j F_{i,j} Fi,j 表示从位置 i i i 出发走 j j j 步的所有路径中经过的所有位置元素和最大的路径对应的元素和。
做法
- 思考答案的计算方法,有 F i , j = max { g i , j , g i − 1 , j − 1 , g i − 2 , j − 2 , ⋯ , g i + 1 , j − 1 , g i + 2 , j − 2 , ⋯ } F_{i,j}=\max\{g_{i,j},g_{i-1,j-1},g_{i-2,j-2},\cdots,g_{i+1,j-1},g_{i+2,j-2},\cdots\} Fi,j=max{gi,j,gi−1,j−1,gi−2,j−2,⋯,gi+1,j−1,gi+2,j−2,⋯},其中 g i , j g_{i,j} gi,j 表示从 i i i 出发往一个方向走 j j j 步的最大结果
- 先预处理出 g g g 的所有元素值,然后分别沿着两条对角线求前缀最大值即可 O ( 1 ) O(1) O(1) 计算出 F F F 的一个元素值
- 但是会 MLE,因此还需要在第二维上滚动数组优化一下