牛客训练赛4 A - Sixteen 题解

A - Sixteen 题解

这题好难。。。

问题重述

给定整数 \(x\)\(|x|<2^{75}\)),构造不超过 \(16\times16\) 的整数矩阵 \(A\),满足:

  • 所有元素 \(A_{i,j}\in[-16,16]\)
  • \(\det(A)=x\)

核心思路

固定 \(n=16\),前 \(15\) 列固定,仅最后一列为变量 \((a_1,\dots,a_{16})^{\mathsf T}\)。由行列式对列线性:

\[\det(A)=\sum_{i=1}^{16}c_i a_i \]

其中系数向量 \((c_1,\dots,c_{16})\) 是前 \(15\) 列的左零空间向量,即对任意 \(j\in[1,15]\)

\[\sum_{i=1}^{16}c_i A_{i,j}=0 \]

问题转化为:设计前 \(15\) 列以产生合适的权值 \(c_i\),再用 \(a_i\in[-16,16]\) 凑出目标 \(x\)


矩阵构造

\(15\) 列固定为:

\[A_{i,j}= \begin{cases} 15, & i=j,\\[2pt] -16, & i=j-1,\\[2pt] 16, & i>j,\\[2pt] 0, & \text{otherwise}. \end{cases} \qquad(i,j\in[1,15]) \]

即:

\[\begin{pmatrix} 15 & -16 & 0 & \cdots & 0 & a_1 \\ 16 & 15 & -16 & \cdots & 0 & a_2 \\ 16 & 16 & 15 & \cdots & 0 & a_3 \\ \vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\ 16 & 16 & 16 & \cdots & 15 & a_{15} \\ 16 & 16 & 16 & \cdots & 16 & a_{16} \end{pmatrix} \]


行变换

从下到上做 \(R_i\leftarrow R_i-R_{i-1}\)\(i=16,\dots,2\)),行列式不变。

前 15 列变化

考察 \(R_i-R_{i-1}\)\(i\ge2\))的前 \(15\) 列:

\(j\) \(R_i\) 原值 \(R_{i-1}\) 原值 差值
\(j<i-1\) \(16\) \(16\) \(0\)
\(j=i-1\) \(16\) \(15\) \(1\)
\(j=i\) \(15\) \(-16\) \(31\)
\(j=i+1\) \(-16\) \(0\) \(-16\)
\(j>i+1\) \(0\) \(0\) \(0\)

变换后前 \(15\) 列为三对角结构(\(R_1\) 不变,\(R_{15}\)\(-16\) 列):

\[\begin{array}{c|cccccc} R_1 & 15 & -16 & 0 & 0 & \cdots & 0 \\ R_2 & 1 & 31 & -16 & 0 & \cdots & 0 \\ R_3 & 0 & 1 & 31 & -16 & \cdots & 0 \\ \vdots & & \ddots & \ddots & \ddots & & \vdots \\ R_{15} & \cdots & 0 & 1 & 31 & 0 & 0 \\ R_{16} & \cdots & 0 & 0 & 1 & 0 & 0 \end{array} \]

最后一列变化

\[b_1=a_1,\qquad b_i=a_i-a_{i-1}\;(i\ge2) \]

将变换后的矩阵记为 \(B\)\(\det B=\det A\)


Laplace 展开与递推序列

沿第 16 列展开

\[\det(B)=\sum_{i=1}^{16}(-1)^{i+16}\,b_i\,M_i \]

其中 \(M_i\) 是删去第 \(i\) 行和第 \(16\) 列后的 \(15\times15\) 余子式。\(i+16\) 为偶数时 \((-1)^{i+16}=(-1)^i\),故:

\[\det(A)=\sum_{i=1}^{16}(-1)^i(a_i-a_{i-1})M_i,\qquad a_0=0 \]

定义 \(D_k\)

\(T\) 为变换后前 \(15\) 列构成的 \(16\times15\) 矩阵。定义 \(D_k\)\(T\) 左上角 \(k\times k\) 主子式的行列式:

\[D_k = \det\begin{pmatrix} 15 & -16 & 0 & \cdots & 0 \\ 1 & 31 & -16 & \cdots & 0 \\ 0 & 1 & 31 & \cdots & 0 \\ \vdots & & \ddots & \ddots & \vdots \\ 0 & \cdots & 0 & 1 & 31 \end{pmatrix}_{k\times k} \]

验证:

\[D_0=1\;(\text{空矩阵}),\quad D_1=15,\quad D_2=\det\begin{pmatrix}15&-16\\1&31\end{pmatrix}=481 \]

\(D_k\) 沿最后一列展开,得递推:

\[D_k=31D_{k-1}+16D_{k-2}\quad(k\ge2) \]

证明 \(M_i=D_{i-1}\)

\(M_i\) 删去第 \(i\) 行和第 \(16\) 列后,剩余的 \(15\times15\) 矩阵分上下两块:

  • 上块(第 \(1\sim i-1\) 行):前 \(i-1\) 列恰为 \(T\) 左上角 \((i-1)\times(i-1)\) 主子式,行列式 \(D_{i-1}\)
  • 下块(第 \(i+1\sim16\) 行):从第 \(i\) 列起为:

\[R_{i+1}:\;[1,31,-16,0,\dots],\; R_{i+2}:\;[0,1,31,-16,\dots],\;\dots,\; R_{16}:\;[\dots,0,1] \]

下块是上三角矩阵,对角元全为 \(1\),行列式为 \(1\)。利用分块行列式性质可得 \(M_i=D_{i-1}\cdot1=D_{i-1}\)

最终展开式

代入 \(M_i=D_{i-1}\)

\[\boxed{\det(A)=\sum_{i=1}^{16}(-1)^i D_{i-1}(a_i-a_{i-1}),\qquad a_0=0} \]


换元

\(a_i=(-1)^i u_i\)\(u_i\in[-16,16]\)。则:

\[a_i-a_{i-1}=(-1)^i(u_i+u_{i-1}),\qquad u_0=0 \]

代入整理:

\[\det(A)=\sum_{i=1}^{15}(D_{i-1}+D_i)u_i+D_{15}u_{16} \]


提取公因子 16

归纳可证 \(D_k\equiv(-1)^k\pmod{16}\),故 \(D_{i-1}+D_i\equiv0\pmod{16}\)

定义:

\[E_k=\frac{D_k+D_{k+1}}{16},\qquad k=0,1,\dots,14 \]

则:

\[\det(A)=16\sum_{k=0}^{14}E_k\,u_{k+1}+D_{15}u_{16} \]


第一步:处理模 16

为什么必做这一步

\(\det(A)=x\),由前述公式:

\[x-D_{15}u_{16}=16\sum_{k=0}^{14}E_k u_{k+1} \]

右边是 \(16\times\)整数,故左边 \(x-D_{15}u_{16}\) 必须被 \(16\) 整除。这不是附加要求,而是等式结构本身的约束。

\(u_{16}\) 吸收模 \(16\) 余数

\(D_{15}\equiv-1\pmod{16}\),所以条件等价于:

\[x+u_{16}\equiv0\pmod{16}\;\Longrightarrow\;u_{16}\equiv-x\pmod{16} \]

为何 \(u_{16}\in[-8,7]\)

区间 \([-8,7]\) 恰好包含 \(16\) 个整数,构成模 \(16\) 的一个完全剩余系,且每个数绝对值最小:

\(u_{16}\) \(-8\) \(-7\) \(-6\) \(-5\) \(-4\) \(-3\) \(-2\) \(-1\) \(0\) \(1\) \(2\) \(3\) \(4\) \(5\) \(6\) \(7\)
\(\bmod16\) \(8\) \(9\) \(10\) \(11\) \(12\) \(13\) \(14\) \(15\) \(0\) \(1\) \(2\) \(3\) \(4\) \(5\) \(6\) \(7\)

因此 \(u_{16}\equiv-x\pmod{16}\)\([-8,7]\) 中有且仅有一个解,唯一性得到保证。

同时 \(D_{15}\) 的量级约为 \(10^{22}\),若 \(|u_{16}|\) 太大,\(Q\) 会额外膨胀并可能超出表示范围。选绝对值最小的代表元,最小化 \(|Q|\),确保后续贪心可行。

归结为纯权值表示

\[Q=\frac{x-D_{15}u_{16}}{16}\in\mathbb Z \]

问题转化为:找 \(u_1,\dots,u_{15}\in[-16,16]\) 使:

\[Q=\sum_{k=0}^{14}E_k\,u_{k+1} \]


权值序列

\[E_0=1,\quad E_1=31, \]

\[E_k=31E_{k-1}+16E_{k-2}\quad(k\ge2) \]

前缀和:

\[S_k=\sum_{j=0}^{k}E_j \]


区间覆盖引理

使用权值 \(E_0,\dots,E_k\),每位系数 \(\in[-16,16]\),可表示区间 \([-16S_k,\,16S_k]\) 中所有整数。

证明(归纳):

  • \(k=0\)\(E_0=1\),系数 \([-16,16]\),显然覆盖 \([-16,16]=[-16S_0,16S_0]\)

  • 归纳:假设 \(E_0,\dots,E_{k-1}\) 覆盖 \([-16S_{k-1},16S_{k-1}]\)。加入 \(E_k\),取系数 \(d\in[-16,16]\) 时覆盖区间:

    \[[dE_k-16S_{k-1},\;dE_k+16S_{k-1}] \]

    相邻 \(d\)\(d+1\) 的区间:

    \[(d+1)E_k-16S_{k-1}-(dE_k+16S_{k-1})=E_k-32S_{k-1} \]

    由递推可证 \(E_k\le32S_{k-1}+1\),故 \(E_k-32S_{k-1}\le1\),相邻区间无缝隙,整体连续覆盖 \([-16S_k,16S_k]\)\(\square\)


可行性验证

计算得 \(16S_{14}=15453918795058662406416\)

\(|x|<2^{75}\)\(|u_{16}|\le8\) 可证:

\[|Q|<9612751694053527819512<16S_{14} \]

\(Q\) 一定可被表示。


第二步:贪心构造 \(u_1\sim u_{15}\)

初始值

\(Q\) 的初始值即为第一步算出的:

\[Q_{\text{init}}=\frac{x-D_{15}u_{16}}{16} \]

贪心流程

从最大权值 \(E_{14}\) 开始,倒序至 \(E_0\)\(k=14,13,\dots,0\)):

  1. 枚举 \(d\in[-16,16]\),找到满足 \(|Q-dE_k|\le16S_{k-1}\)\(d\)
  2. \(u_{k+1}=d\)
  3. 更新 \(Q\leftarrow Q-dE_k\)(剩余量缩小)。

直观理解

\[Q_{\text{init}}\;\xrightarrow{\;k=14\;}\;\text{剩余量}\;\xrightarrow{\;k=13\;}\;\cdots\;\xrightarrow{\;k=0\;}\;0 \]

每一步从 \(Q\) 中扣除 \(d\cdot E_k\),将表示范围从 \([-16S_k,16S_k]\) 收缩到 \([-16S_{k-1},16S_{k-1}]\)\(Q\) 始终保持在下标 \(k\) 对应的可达区间内,最终归零。

区间覆盖引理保证每一步必存在合法 \(d\)


第三步:回填矩阵

\(a_i=(-1)^i u_i\),填入第 \(16\) 列。前 \(15\) 列按模板填入。

输出 \(n=16\) 及完整矩阵。


复杂度

每条用例枚举 \(15\times33\) 个候选值,常数时间。总复杂度 \(O(T)\)


参考实现

#include<bits/stdc++.h>
using namespace std;
using i128=__int128;
constexpr int N=16;
i128 D[N+1],E[N],S[N];
i128 read(){
    string s; 
    cin>>s;
    i128 x=0; 
    int f=1,i=0;
    if(s[0]=='-') f=-1,i=1;
    for(;i<(int)s.size();++i) x=x*10+(s[i]-'0');
    return f*x;
}
void init(){
    D[0]=1,D[1]=15;
    for(int i=2;i<=N;++i) D[i]=31*D[i-1]+16*D[i-2];
    for(int i=0;i<N;++i) E[i]=(D[i]+D[i+1])/16;
    S[0]=E[0];
    for(int i=1;i<N;++i) S[i]=S[i-1]+E[i];
}
i128 ABS(i128 x){
    if(x>=0) return x;
    else return -x;
}
void sol(i128 x){
    int u16=((-x)%16+16)%16;
    if(u16>7) u16-=16;
    i128 Q((x-D[15]*u16)/16);
    vector<int> u(N);
    u[15]=u16;
    for(int k=14;k>=0;--k){
        for(int d=-16;d<=16;++d){
            i128 rem=ABS(Q-d*E[k]);
            i128 bound((!k?0:16*S[k-1]));
            if(rem<=bound){
                u[k]=d;
                Q=Q-d*E[k];
                break;
            }
        }
    }
    cout<<N<<'\n';
    for(int i=0;i<N;++i){
        for(int j=0;j<N;++j){
            int val;
            if(j<N-1){
                if(i==j) val=15;
                else if(i+1==j) val=-16;
                else if(i>j) val=16;
                else val=0;
            }else val=(i&1?1:-1)*u[i];
            cout<<val<<' '; 
        }
        cout<<'\n';
    }
}
int main(){
    init();
    int T(1);
    cin>>T;
    while(T--) sol(read());
}
posted @ 2026-09-15 22:35  Melting_Pot  阅读(6)  评论(0)    收藏  举报