题面传送门

emmm……怎么评价这个题呢,赛后学完差分约束之后看题解感觉没那么 dl,可是现场为啥就因为种种原因想不到呢?显然是 wtcl(

先不考虑“非负“及” \(\le 10^6\) ”这两条件,考虑什么样的矩阵 \(A\) 能够生成 \(B\),我们首先考虑矩阵 \(A\) 的一个特解 \(A'\):第一行和第一列都是 \(0\) 的情况,显然 \(A'\) 可以通过一遍反着递推求出。接下来考虑怎样通过 \(A'\) 推出所有符合要求的矩阵 \(A\),一个显然的事实是如果确定了该矩阵 \(A\) 的第一行和第一列,那么最终的矩阵就定下来了。注意到 \(A\) 的第一行第一列的元素 \(A_{11}\) 是有点特别的,因为它既在第一行又在第一列,我们先忽略它,暂且将它定为 \(0\)。我们考虑对于某个 \(i\ne 1\),将 \(A_{1i}\)(或 \(A_{i1}\))由 \(0\) 变为 \(v\) 对整个矩阵 \(A\) 产生的影响,以 \(A_{1i}\) 为例,手玩几组数据就可以发现若 \(A_{1i}\) 变成 \(v\),那么 \(A_{2i}\) 会减去 \(v\),\(A_{3i}\) 会加上 \(v\),\(A_{4i}\) 又会减去 \(v\),以此类推。我们假设 \(x_i=A_{i1},y_i=A_{1i}\),那么

\[A=A'+\begin{bmatrix}
0&y_2&y_3&\cdots&y_j&\cdots&y_m\\
x_2&-x_2-y_2&x_2-y_3&\cdots&(-1)^{j+1}x_2-y_j&\cdots&(-1)^{m+1}x_2-y_m\\
\vdots&\vdots&\vdots&\ddots&\vdots&\ddots&\vdots\\
x_i&-x_i+(-1)^{i+1}y_2&x_i+(-1)^{i+1}y_3&\cdots&(-1)^{j+1}x_i+(-1)^{i+1}y_j&\cdots&(-1)^{m+1}x_i+(-1)^{i+1}y_m\\
\vdots&\vdots&\vdots&\ddots&\vdots&\ddots&\vdots\\
x_n&-x_n+(-1)^{n+1}y_2&x_n+(-1)^{n+1}y_3&\cdots&(-1)^{j+1}x_n+(-1)^{n+1}y_j&\cdots&(-1)^{m+1}x_n+(-1)^{n+1}y_m
\end{bmatrix}
\]

考虑加上 \(A_{11}\) 之后的影响,那么 \(A_{ij}\) 会加上 \((-1)^{i+j+1}A_{11}\),这个看起来有点棘手,怎么办呢?我们考虑设 \(A_{11}=x_1+y_1\)(这个 \(x_1\) 可以为任意整数),我们令新的 \(x_i\leftarrow x_i+(-1)^{i}y_1\),再令新的 \(y_i\leftarrow y_i+(-1)^ix_1\),不难发现经过这样的转化之后,\(A_{i,j}\) 由原来的 \(A'_{i,j}+(-1)^{j+1}x_i+(-1)^{i+1}y_j\) 变为 \(A'_{i,j}+(-1)^{j+1}(x_i+(-1)^iy_1)+(-1)^{i+1}(y_j+(-1)^jx_1)=A'_{i,j}+(-1)^{j+1}x_i+(-1)^{i+1}y_j+(-1)^{i+j+1}(x_1+y_1)\)(注:该式子中的 \(x_i,y_i\) 为原来的 \(x_i,y_i\),下同)刚好就是新的 \(A_{i,j}\),但是这样第一行第一列的值就不对了,此时考虑再令 \(A_{i1}=x_i+(-1)^{i+1}y_1\),\(A_{1i}=y_i+(-1)^{i+1}x_1\),这样新的 \(A_{1i}=x_i+(-1)^{i}y_1+(-1)^{i+1}y_1\) 刚好就是原来的 \(x_i\),\(A_{i1}\) 也同理。因此新的 \(A_{i,j}=A'_{i,j}+(-1)^{j+1}x_i+(-1)^{i+1}y_j\),就不用考虑 \(i,j\) 是否为 \(1\),显然一组 \(x,y\) 对应一个生成 \(B\) 的矩阵 \(A\),而一个对于 \(A\) 又存在合法的 \(x,y\),因此我们只用求出合法的 \(x_i,y_j\) 即可构造出符合要求的 \(A\)

我们考虑 \(A_{i,j}\) 非负这个条件的具体作用,由于涉及 \((-1)^i\) 这种形式的东西,因此按 \(i,j\) 的奇偶性分类讨论:

  • \(i\) 为奇数,\(j\) 为奇数,\(0\le x_i+y_j+A'_{i,j}\le 10^6\)
  • \(i\) 为奇数,\(j\) 为偶数,\(0\le -x_i+y_j+A'_{i,j}\le 10^6\)
  • \(i\) 为偶数,\(j\) 为奇数,\(0\le x_i-y_j+A'_{i,j}\le 10^6\)
  • \(i\) 为偶数,\(j\) 为偶数,\(0\le -x_i-y_j+A'_{i,j}\le 10^6\)

中间两个都可通过某种方式转化为差分约束的标准形式,关键是前两个怎么处理,其实也比较 simple,我们令 \(x'_i=(-1)^{i+1}x_i,y'_i=(-1)^iy_i\),那么上面四种情况又可写作:

  • \(i\) 为奇数,\(j\) 为奇数,\(0\le x'_i-y'_j+A'_{i,j}\le 10^6\)
  • \(i\) 为奇数,\(j\) 为偶数,\(0\le -x'_i+y'_j+A'_{i,j}\le 10^6\)
  • \(i\) 为偶数,\(j\) 为奇数,\(0\le -x'_i+y'_j+A'_{i,j}\le 10^6\)
  • \(i\) 为偶数,\(j\) 为偶数,\(0\le x'_i-y'_j+A'_{i,j}\le 10^6\)

这下四个式子都可以转化为差分约束的形式了,直接差分约束建出图来判个负环即可。

时间复杂度 \(Tn^3\)

这里有一个小小的细节以前一直没有注意过,这里稍微提一下,就是判负环过程中的“松弛次数”只要 \(dis\) 值被更新了就行,不一定指“入队次数”,这样常数会小一些,否则对于 NO 的数据可能要跑很久,我一直为此 TLE 50,交了 \(114514191981019260817998244353\) 发(bushi)

代码异常好写:

const int MAXN=300;
const int MAXV=600;
const int MAXE=300*300*2;
int n,m,a[MAXN+5][MAXN+5],b[MAXN+5][MAXN+5];
int hd[MAXV+5],to[MAXE+5],nxt[MAXE+5],val[MAXE+5],ec=0;
void adde(int u,int v,int w){to[++ec]=v;val[ec]=w;nxt[ec]=hd[u];hd[u]=ec;}
bool inq[MAXV+5];ll dis[MAXV+5];int in[MAXV+5];
void clear(){
memset(b,0,sizeof(b));
memset(hd,0,sizeof(hd));ec=0;
memset(in,0,sizeof(in));
memset(dis,0,sizeof(dis));
memset(inq,0,sizeof(inq));//注意清空 inq 数组,因为有可能出现判到负环就 return 的清空,所以最后 inq[i] 不一定是 0
}
void solve(){
scanf("%d%d",&n,&m);clear();
for(int i=1;i<n;i++) for(int j=1;j<m;j++) scanf("%d",&a[i][j]);
for(int i=2;i<=n;i++) for(int j=2;j<=m;j++) b[i][j]=a[i-1][j-1]-b[i-1][j]-b[i][j-1]-b[i-1][j-1];
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
if(~(i+j)&1) adde(i,j+n,b[i][j]),adde(j+n,i,1e6-b[i][j]);//x[i]-y[j]
else adde(j+n,i,b[i][j]),adde(i,j+n,1e6-b[i][j]);//y[j]-x[i]
} queue<int> q;
for(int i=1;i<=n+m;i++) q.push(i),inq[i]=1;
while(!q.empty()){
int x=q.front();q.pop();inq[x]=0;
for(int e=hd[x];e;e=nxt[e]){
int y=to[e],z=val[e];
if(dis[y]>dis[x]+z){
dis[y]=dis[x]+z;
if(++in[y]>n+m) return puts("NO"),void();//这边稍微注意下,不一定要写到下面一个 if 中
if(!inq[y]) q.push(y),inq[y]=1;
}
}
}
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
if(~(i+j)&1) b[i][j]+=dis[i]-dis[j+n];
else b[i][j]+=dis[j+n]-dis[i];
} printf("YES\n");
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) printf("%d%c",b[i][j]," \n"[j==m]);
}
int main(){int qu;scanf("%d",&qu);while(qu--) solve();return 0;}

洛谷 P7515 - [省选联考 2021 A 卷] 矩阵游戏(差分约束)的更多相关文章

  1. [省选联考 2021 A 卷] 矩阵游戏

    很巧妙的一个构造. 我是没有想到的. 自己的思维能力可能还是不足. 考虑先满足\(b\)对\(a\)的限制,把\(a\)的第一行和第一列设\(0\),推出这个\(a\). 接下来考虑对这个\(a\), ...

  2. 洛谷 P7520 - [省选联考 2021 A 卷] 支配(支配树)

    洛谷题面传送门 真·支配树不 sb 的题. 首先题面已经疯狂暗示咱们建出支配树对吧,那咱就老老实实建呗.由于这题数据范围允许 \(n^2\)​ 算法通过,因此可以考虑 \(\mathcal O(n^2 ...

  3. 洛谷 P7516 - [省选联考 2021 A/B 卷] 图函数(Floyd)

    洛谷题面传送门 一道需要发现一些简单的性质的中档题(不过可能这道题放在省选 D1T3 中偏简单了?) u1s1 现在已经是 \(1\text{s}\)​ \(10^9\)​ 的时代了吗?落伍了落伍了/ ...

  4. 洛谷P6623——[省选联考 2020 A 卷] 树

    传送门:QAQQAQ 题意:自己看 思路:正解应该是线段树/trie树合并? 但是本蒟蒻啥也不会,就用了树上二次差分 (思路来源于https://www.luogu.com.cn/blog/dengy ...

  5. 洛谷 P6624 - [省选联考 2020 A 卷] 作业题(矩阵树定理+简单数论)

    题面传送门 u1s1 这种题目还是相当套路的罢 首先看到 \(\gcd\) 可以套路地往数论方向想,我们记 \(f_i\) 为满足边权的 \(\gcd\) 为 \(i\) 的倍数的所有生成树的权值之和 ...

  6. [题解] LOJ 3300 洛谷 P6620 [省选联考 2020 A 卷] 组合数问题 数学,第二类斯特林数,下降幂

    题目 题目里要求的是: \[\sum_{k=0}^n f(k) \times X^k \times \binom nk \] 这里面出现了给定的多项式,还有组合数,这种题目的套路就是先把给定的普通多项 ...

  7. [省选联考 2021 A/B 卷] 卡牌游戏

    垃圾福建垫底选手来看看这题. 大家怎么都写带 \(log\) 的. 我来说一个线性做法好了. 那么我们考虑枚举 \(k\) 作为翻转完的最小值. 那么构造出一个满足条件的操作,我们在 \(a_i\) ...

  8. [省选联考 2020 A 卷] 组合数问题

    题意 [省选联考 2020 A 卷] 组合数问题 想法 自己在多项式和数论方面还是太差了,最近写这些题都没多少思路,看完题解才会 首先有这两个柿子 \(k*\dbinom{n}{k} = n*\dbi ...

  9. luoguP6623 [省选联考 2020 A 卷] 树(trie树)

    luoguP6623 [省选联考 2020 A 卷] 树(trie树) Luogu 题外话: ...想不出来啥好说的了. 我认识的人基本都切这道题了. 就我只会10分暴力. 我是傻逼. 题解时间 先不 ...

随机推荐

  1. mac无坑安装nginx

    mac无坑安装nginx 首先需要mac下有一个缺失的软件包的管理器------->homebrew 1.打开终端输入 brew update 说明homebrew已经安装好了 2.继续执行以下 ...

  2. WPF 排版基础

    一.WPF 排版基础 WPF使用控制面板来进行排版,控制面板实际上是一种可以放入WPF界面元素的容器.当用户把界面元素放入控制面板后,WPF会自动把这些界面元素放在它认为合适的地方.WPF开发人员需要 ...

  3. Coursera Deep Learning笔记 深度卷积网络

    参考 1. Why look at case studies 介绍几个典型的CNN案例: LeNet-5 AlexNet VGG Residual Network(ResNet): 特点是可以构建很深 ...

  4. Beta_Scrum Meeting_0

    日期:2021年5月26日 参会人员:cy.hcc.lsc.dxh 会议主题:为Beta阶段最早两日的开发制定目标 一.进度情况 组员 负责 两日内完成的任务 接下来两日预计完成的任务 hcc 前端 ...

  5. 排序算法:Java实现希尔排序

    希尔排序的思路是先分组再整合 先对下标进行分组,比如当数组长度为20时,一开始选定一个间隔值为10 对数组进行排序,每隔10个元素比较大小并交换,以下标为间隔,1和11比较.2和12比较......1 ...

  6. vs2015 MSB600 "inf2cat.ext"已退出,代码为2

    使用vs2015编译XDMA驱动过程中,报如下错误: vs2015 MSB600 "inf2cat.ext"已退出,代码为2 在使用Qt编译PCIE码表的过程中,出现C1038:无 ...

  7. Centos 7 端口聚合

    简单粗暴,直接复制命令就好了 还是先啰嗦一下,添加网卡之后,如果没有网卡配置文件,可以通过nmcli con show 先查看网卡的唯一ID,然后复制其他的网卡配置文件,修改device项,name项 ...

  8. 字符编码之间的转换 utf-8 , gbk等,(解决中文字符串乱码)

    目录 1.背景. 2.编码的理解 3.编码之间的相互转化 4. str类型说明 5. 可以使用的编码类型 6.参考文章 1.背景 Python中与其他程序进行交互时,如果存在字符串交互,特别是字符串中 ...

  9. UVA1104 Chips Challenge

    一.题目 有一个 \(n\times n\) 的矩阵,每个元素可能是 ..C./ 的其中一种,分别表示可以放置芯片.已经放置了芯片.不能放置芯片,你可以分别决定是否可以放置芯片的位置放置芯片. 最后需 ...

  10. Jenkins 邮件发送

    1.jenkins新建任务 2.配置svn 3.maven项目构建配置pom.xml 使用maven命令 clean test 构建前清除: 4.系统管理 => 插件管理 =>可选安装邮件 ...