2026 码蹄杯初赛第一场

Written by: Joyce-Peng-GitHub

码蹄杯初赛第一场

5.

给定矩阵a∈Nm×m, b∈Nn×n (m,n∈N∗, m≥n)a\in\mathbb{N}^{m\times m},\ b\in\mathbb{N}^{n\times n}\ (m,n\in\mathbb{N^*},\ m\geq n),求

(∑i=0m−n∑j=0m−n∑k=0n−1∑l=0n−1(ai+k,j+l⊕bk.l)) mod (109+7).\left(\sum_{i=0}^{m-n}\sum_{j=0}^{m-n}\sum_{k=0}^{n-1}\sum_{l=0}^{n-1}(a_{i+k,j+l}\oplus b_{k.l})\right)\bmod(10^9+7).

保证m,n≤103, (∀i) (∀j) (ai,j,bi,j≤109)m,n\leq10^3,\ (\forall i)\ (\forall j)\ (a_{i,j},b_{i,j}\leq10^9)。

按位异或对加法不满足分配律,所以直接化简这个和式是不可能的。考虑按位处理。用x(p)x^{(p)}表示xx从低到高的第pp位。

考虑贡献法,ai,ja_{i,j}与哪些元素进行了异或?于是原和式可以化为

∑i=0m−1∑j=0m−1∑k=max⁡{i−(m−n),0}min⁡{i,n−1}∑l=max⁡{j−(m−n),0}min⁡{j,n−1}(ai,j⊕bk,l).\sum_{i=0}^{m-1}\sum_{j=0}^{m-1}\sum_{k=\max\{i-(m-n),0\}}^{\min\{i,n-1\}}\sum_{l=\max\{j-(m-n),0\}}^{\min\{j,n-1\}}(a_{i,j}\oplus b_{k,l}).

记

kmin⁡=max⁡{i−(m−n),0}, kmax⁡=min⁡{i,n−1},lmin⁡=max⁡{j−(m−n),0}, lmax⁡=min⁡{j,n−1},\begin{array}{c} k_{\min}=\max\{i-(m-n),0\},\ k_{\max}=\min\{i,n-1\},\\ l_{\min}=\max\{j-(m-n),0\},\ l_{\max}=\min\{j,n-1\}, \end{array}

按位考虑,则原和式等于

∑b=0B−1∑i=0m−1∑j=0m−1∑k=kmin⁡kmax⁡∑l=lmin⁡lmax⁡(ai,j(p)⊕bi,j(p))⋅2p,\sum_{b=0}^{B-1}\sum_{i=0}^{m-1}\sum_{j=0}^{m-1}\sum_{k=k_{\min}}^{k_{\max}}\sum_{l=l_{\min}}^{l_{\max}}(a_{i,j}^{(p)}\oplus b_{i,j}^{(p)})\cdot2^p,

其中B=⌈log⁡(109)⌉B=\lceil\log(10^9)\rceil。

对于取定的i,j,pi,j,p,由异或的定义可知,我们只需数出bb在区域N2∩([kmin⁡,kmax⁡]×[lmin⁡,lmax⁡])\mathbb{N}^2\cap([k_{\min},k_{\max}]\times[l_{\min},l_{\max}])中00或11的数量即可。当ai,j(p)=0a_{i,j}^{(p)}=0时数11,当ai,j=1a_{i,j}=1时数00。这个计数值可以通过Θ(n2)\varTheta(n^2)预处理二维前缀和来Θ(1)\varTheta(1)求出。

7.

给定a∈(N∗)3×n (n∈N∗)a\in(\mathbb{N}^*)^{3\times n}\ (n\in\mathbb{N}^*),求

(a0,⌊i/n2⌋⋅a1,⌊i/n⌋ mod n⋅a2,i mod n)i=0n3−1(a_{0,\lfloor i/n^2\rfloor}\cdot a_{1,\lfloor i/n\rfloor\bmod n}\cdot a_{2,i\bmod n})_{i=0}^{n^3-1}

中最小的m∈N∗m\in\mathbb{N}^*项。保证n≤105, m≤min⁡{n3,2n}, (∀i∈{0,1,2}) (∀i) (∀j) (ai,j≤105)n\leq10^5,\ m\leq\min\{n^3,2n\},\ (\forall i\in\{0,1,2\})\ (\forall i)\ (\forall j)\ (a_{i,j}\leq10^5)。

我真傻,真的。

可以先用a0,a1a_0,a_1组合一遍乘积,用最小的mm个再去与a2a_2组合一遍。这一点我没想到。

用堆维护最小的mm项是很容易想到的。

但这样还不够!暴力组合两个数组,复杂度仍然高达Θ(n2log⁡m)\varTheta(n^2\log m),我们需要找到更高效的寻找最小mm个乘积的方式。很容易想到将它们先排序,然后怎么办?

如果我们将这两个数组组合的过程列成表格(以a0,a1a_0,a_1分别作纵轴和横轴,表格中填上乘积),那末每一行、每一列都必定是递增的。现在我们的任务变为一个经典问题(多路归并问题):如何在这nn行(从列的视角看当然也可以,这是等价的)已经有序的数列中选出最小的mm个?很显然只需对各行维护一个从左往右移动的指针,指向下一个待选元素;每次选取所有待选元素中最小的那一个,并移动指针即可;而“选取所有待选元素中最小的那一个”正适合用一个小根堆来维护。进一步地,由于我们/只需求出最小的mm个元素,我们只需考虑前min⁡{m,n}\min\{m,n\}行即可,因为第m+1m+1行(如果存在)的首个元素必定比前mm行的首个元素更大。