Other
luogu1102 数对
(2022.4 8)
给你一个长度为 n ∈ [ 1 , 2 e 5 ] n \in [1, 2e5] n∈[1,2e5] 的数列(数列中的数 a i ∈ [ 1 , 2 30 ] a_i \in [1, 2^{30}] ai∈[1,230])和一个整数 C C C,然后让你找出这个数列中所有位置不同的两个数 A , B A, B A,B。并统计满足 A − B = C A - B = C A−B=C 的数对的个数。
挺水的一道题。我们把条件转化一下,把 A − B = C A - B = C A−B=C 转化成 A − C = B A - C = B A−C=B。然后我们只用建立一个 m a p map map, m [ a [ i ] ] m[a[i]] m[a[i]] 表示 a [ i ] a[i] a[i] 在 { a } \{a\} {a} 中出现的次数。然后 a n s = ∑ i = 1 n m [ a [ i ] − C ] ans = \sum\limits_{i = 1}^nm[a[i] - C] ans=i=1∑nm[a[i]−C]。就搞定了。
luogu2671 求和
(2022.4.9)
现在有一个数组,每个数三个值 ( x , y , c ) (x, y, c) (x,y,c)。分别表示下标,值和颜色。如果我们找到一个三元组 ( i , j , k ) (i, j, k) (i,j,k) 满足 j j j 是 i , k i, k i,k 的等差中项且下标分别为 i i i 和 k k k 的所对应的颜色相同,那么这个三元组就对答案有 ( x i + x k ) × ( y i + y k ) (x_i + x_k) \times (y_i + y_k) (xi+xk)×(yi+yk) 的贡献。求总答案。
首先我们发现 j j j 其实没啥用,这里只是规定了 i i i 和 k k k 必须奇偶性相同。所以我们考虑单独把能对答案产生贡献的块放到一起。也就是按颜色为第一关键字, x x x 的奇偶性按第二关键字排序。然后分别处理每一块对答案的贡献,然后再加起来就可以了。
这里以处理第一块对答案的贡献为例(假设第一块的长度为 k k k)。那么这块的贡献就是:
∑ i = 1 k ∑ j = i + 1 k ( x i + x j ) ( y i + y j ) = ∑ i = 1 k ∑ j = i + 1 k ( x i y i + x j y j + x i y j + x j y i ) = ∑ i = 1 k ( ∑ j = i + 1 k x i y i + ∑ j = i + 1 k x j y j + ∑ j = i + 1 k x i y j + ∑ j = i + 1 k x j y i ) = ∑ i = 1 k ( ( k − i ) x i y i + ∑ j = i + 1 k x j y j + x i ∑ j = i + 1 k y j + y i ∑ j = i + 1 k x j ) \begin{aligned} & \sum_{i = 1}^k\sum_{j = i + 1}^k(x_i + x_j)(y_i +y_j) \\ = & \sum_{i=1}^k\sum_{j=i +1}^k(x_iy_i + x_jy_j + x_iy_j + x_jy_i) \\ = & \sum_{i = 1}^k \left( \sum_{j = i +1}^k x_iy_i + \sum_{j = i +1}^k x_jy_j + \sum_{j = i +1}^kx_iy_j + \sum_{j = i +1}^kx_jy_i \right) \\ = &\sum_{i = 1}^k \left( (k - i)x_iy_i + \sum_{j = i +1}^kx_jy_j + x_i\sum_{j = i +1}^ky_j + y_i\sum_{j = i +1}^kx_j \right) \\ \end{aligned} ===i=1∑kj=i+1∑k(xi+xj)(yi+yj)i=1∑kj=i+1∑k(xiyi+xjyj+xiyj+xjyi)i=1∑k(j=i+1∑kxiyi+j=i+1∑kxjyj+j=i+1∑kxiyj+j=i+1∑kxjyi)i=1∑k((k−i)xiyi+j=i+1∑kxjyj+xij=i+1∑kyj+yij=i+1∑kxj)
然后我们发现只要我们预处理出 x i x_i xi、 y i y_i yi 和 x i y i x_iy_i xiyi 的前缀和,我们就能 O ( 1 ) O(1) O(1) 处理我们用很大的括号括起来的那一坨式子。这样整个的复杂度就是 O ( k ) O(k) O(k) 的。
单调队列
WOJ4744 最佳序列
(2022.4.3)
给定一个长度为 n n n 的数组 a a a。给定 L , R L, R L,R,求所有满足长度大于等于 L L L 小于等于 R R R 的 a a a 的子区间的平均值的最大。
先二分答案,也就是二分平均值,然后每个数减去这个平均值,这个时候所有和大于 0 0 0 的区间的平均值就肯定大于二分的值。
统计减去平均值的后序列的前缀和,问题就变成了前缀和在 [ i − R , i − L ] [i - R, i - L] [i−R,i−L] 区间内是否存在一个数 s j s_j sj 使得 s i > s j s_i > s_j si>sj,然后就是单调队列优化就能做到 O ( n ) O(n) O(n)。
luogu2216 理想正方形
(2022.4.9)
给你一个 a × b a \times b a×b 的二维数组( a , b ∈ [ 2 , 1 e 3 ] a, b \in[2, 1e3] a,b∈[2,1e3])。然后再给你一个 n ≤ a , b n \leq a, b n≤a,b,让你在这个二维数组中找到一个 n × n n \times n n×n 的矩形使得这个矩形中的最大值减这个矩形中的最小值是最小的。
很显然这是一个 R M Q RMQ RMQ 的问题,因为 a a a 和 b b b 不大,而且 n n n 是确定的,所以我们考虑跑 a + b a + b a+b 遍单调队列来处理这道题,具体做法如下:
我们以 l u o g u luogu luogu 上的样例为例 n = 2 n = 2 n=2,我们先横着跑单调队列求出每一行连续 n n n 个中的最大值。
1 2 5 6 0 17 16 0 16 17 2 1 2 10 2 1 1 2 2 2 → 2 5 6 17 17 16 17 17 2 10 10 2 2 2 2 \begin{matrix} 1 & 2 & 5 & 6 \\ 0 & 17 &16 & 0 \\ 16 & 17 & 2 & 1 \\ 2 & 10 & 2 & 1 \\ 1 & 2 & 2 & 2 \\ \end{matrix} \quad \to \quad \begin{matrix} 2 & 5 & 6 \\ 17 &17 & 16 \\ 17 & 17 & 2 \\ 10 & 10 & 2 \\ 2 & 2 & 2 \\ \end{matrix} 1016212171710251622260112→2171710251717102616222
然后再竖着跑单调队列求出每一列中连续 n n n 个数的最大值:
2 5 6 17 17 16 17 17 2 10 10 2 2 2 2 → 17 17 16 17 17 16 17 17 2 10 10 2 \begin{matrix} 2 & 5 & 6 \\ 17 &17 & 16 \\ 17 & 17 & 2 \\ 10 & 10 & 2 \\ 2 & 2 & 2 \\ \end{matrix} \quad \to \quad \begin{matrix} 17 &17 & 16 \\ 17 & 17 & 16 \\ 17 & 17 & 2 \\ 10 & 10 & 2 \\ \end{matrix} 2171710251717102616222→1717171017171710161622
同理,我们对最小值也这样处理:
1 2 5 6 0 17 16 0 16 17 2 1 2 10 2 1 1 2 2 2 → 1 2 5 0 16 0 16 2 1 2 2 1 1 2 2 → 0 2 0 0 2 0 2 2 1 1 2 1 \begin{matrix} 1 & 2 & 5 & 6 \\ 0 & 17 &16 & 0 \\ 16 & 17 & 2 & 1 \\ 2 & 10 & 2 & 1 \\ 1 & 2 & 2 & 2 \\ \end{matrix} \quad \to \quad \begin{matrix} 1 & 2 & 5 \\ 0 &16 & 0 \\ 16 & 2 & 1 \\ 2 & 2 & 1 \\ 1 & 2 & 2 \\ \end{matrix} \quad \to \quad \begin{matrix} 0 &2 & 0 \\ 0 & 2 & 0 \\ 2 & 2 & 1 \\ 1 & 2 & 1 \\ \end{matrix} 1016212171710251622260112→10162121622250112→002122220011
然后将跑出来的两个矩阵相减,找到差矩阵中的最小值即为所求:
17 17 16 17 17 16 17 17 2 10 10 2 − 0 2 0 0 2 0 2 2 1 1 2 1 = 17 15 16 17 15 16 15 15 1 9 8 1 \begin{matrix} 17 &17 & 16 \\ 17 & 17 & 16 \\ 17 & 17 & 2 \\ 10 & 10 & 2 \\ \end{matrix} \quad - \quad \begin{matrix} 0 &2 & 0 \\ 0 & 2 & 0 \\ 2 & 2 & 1 \\ 1 & 2 & 1 \\ \end{matrix} \quad = \quad \begin{matrix} 17 & 15 & 16 \\ 17 & 15 & 16 \\ 15 & 15 & 1 \\ 9 & 8 & 1 \\ \end{matrix} 1717171017171710161622−002122220011=17171591515158161611
答案就是 1 1 1
启发式合并
luogu3201 HNOI2009 梦幻布丁
(2022.4.11)
初始给以一个长度为 n n n 的数列,这个数列的每个数表示一个颜色,然后给你 m m m 个操作,每次操作或是查询现在颜色的总段数(例如 1 , 2 , 2 , 1 1, 2, 2, 1 1,2,2,1 就是有 3 3 3 段颜色)或是给定 x , y x, y x,y 表示将颜色 x x x 的数全部变为 y y y 颜色。
显然这道题就是一个链表的启发式合并,我们维护很多链表,每个链表中存出同一种颜色的数。然后每一次修改就是一次启发式合并,对于询问我们可以在修改的时候处理出来,具体来说就是:如果(假设 x x x 是元素较少的那个集合) x x x 中的一个元素旁边有有 y y y 中的元素的话那么 a n s ans ans 就应该减 1 1 1。
这样虽然看起来很暴力,但是时间复杂度就是启发式合并的时间复杂度也就是 O ( n log n ) O(n\log n) O(nlogn) 的。