正题
题目链接:https://www.luogu.com.cn/problem/P7515
题目大意
有一个n∗mn*mn∗m的矩形AAA,然后给出一个(n−1)∗(m−1)(n-1)*(m-1)(n−1)∗(m−1)的矩形BBB满足
Bi,j=Ai,j+Ai+1,j+Ai,j+1+Ai+1,j+1B_{i,j}=A_{i,j}+A_{i+1,j}+A_{i,j+1}+A_{i+1,j+1}Bi,j=Ai,j+Ai+1,j+Ai,j+1+Ai+1,j+1
求能否构造合法矩形AAA使得0≤ai,j≤1060\leq a_{i,j}\leq 10^60≤ai,j≤106
1≤T≤10,1≤n,m≤300,0≤bi,j≤4×1061\leq T\leq 10,1\leq n,m\leq 300,0\leq b_{i,j}\leq 4\times 10^61≤T≤10,1≤n,m≤300,0≤bi,j≤4×106
解题思路
如果不考虑ai,ja_{i,j}ai,j的限制显然很容易构造一个方案。
然后要考虑怎么调整到满足限制,不难发现我们每行/列进行+1/−1/+1/−1...+1/-1/+1/-1...+1/−1/+1/−1...操作不会改变bbb数组上的值,所以我们设cic_ici表示第iii行进行了多少次,第jjj行进行了多少次,那么有
0≤ai,j±ci±dj≤1060\leq a_{i,j}±c_i±d_j\leq 10^60≤ai,j±ci±dj≤106
如果我们控制使得每个位置的cic_ici和djd_jdj的符号不同那么就可以进行差分约束了。
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define ll long long
using namespace std;
const ll N=610;
struct node{ll to,next,w;
}a[N*N];
ll T,n,m,b[N][N],c[N][N];
ll tot,cnt[N],ls[N],f[N];
bool v[N];deque<int> q;
void addl(ll x,ll y,ll w){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;a[tot].w=w;return;
}
bool SPFA(){memset(f,0x3f,sizeof(f));memset(cnt,0,sizeof(cnt));q.push_back(1);v[1]=cnt[1]=1;f[1]=0;while(!q.empty()){ll x=q.front();v[x]=0;q.pop_front();for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(f[x]+a[i].w<f[y]){f[y]=f[x]+a[i].w;cnt[y]=cnt[x]+1;if(cnt[y]>=n+m&&a[i].w<0)return 1;if(!v[y]){v[y]=1;if(!q.empty()&&f[y]<f[q.front()])q.push_front(y);else q.push_back(y);}}}}return 0;
}
signed main()
{scanf("%lld",&T);while(T--){memset(ls,0,sizeof(ls));tot=0;scanf("%lld%lld",&n,&m);for(ll i=1;i<n;i++)for(ll j=1;j<m;j++)scanf("%lld",&b[i][j]);memset(c,0,sizeof(c));for(ll i=1;i<=m;i++)c[1][i]=0;for(ll i=2;i<=n;i++){c[i][1]=0;for(ll j=2;j<=m;j++)c[i][j]=b[i-1][j-1]-c[i-1][j-1]-c[i-1][j]-c[i][j-1];}for(ll i=1;i<=n;i++)for(ll j=1;j<=m;j++){if((i+j)&1)addl(i,j+n,c[i][j]),addl(j+n,i,1e6-c[i][j]);else addl(j+n,i,c[i][j]),addl(i,j+n,1e6-c[i][j]);}if(!SPFA()){puts("YES");for(ll i=1;i<=n;i++,putchar('\n'))for(ll j=1;j<=m;j++){if((i+j)&1)c[i][j]=c[i][j]+f[i]-f[j+n];else c[i][j]=c[i][j]-f[i]+f[j+n];printf("%lld ",c[i][j]);}}else puts("NO");}return 0;
}