zoukankan      html  css  js  c++  java
  • [loj3500]矩阵游戏

    为了方便,令$a_{i,j}$的下标范围为$[0,n]$和$[0,m]$,$b_{i,j}$的下标范围为$[1,n]$和$[1,m]$

    当确定$a_{i,0}$和$a_{0,j}$后,即可通过$b_{i,j}$来确定$a_{i,j}$,具体的有
    $$
    a_{i,j}=(-1)^{i+j}sum_{1le xle i,1le yle j}(-1)^{x+y}b_{x,y}+(-1)^{j}a_{i,0}+(-1)^{i}a_{0,j}-(-1)^{i+j}a_{0,0}
    $$
    由于在$i=0$或$j=0$时其也满足该式子,因此现在的条件变为:构造任意整数$a_{i,0}$和$a_{0,j}$,使得对于任意$i$和$j$(符合下标范围),上述式子计算得到后的结果在$[0,V]$中(其中$V=10^{6}$)

    提出$(-1)^{i+j}$,再令$B_{i,j}=sum_{1le xle i,1le yle j}(-1)^{x+y}b_{x,y}$,即有
    $$
    a_{i,j}=(-1)^{i+j}(B_{i,j}+(-1)^{i}a_{i,0}+(-1)^{j}a_{0,j}-a_{0,0})
    $$
    令$x_{i}=(-1)^{i}a_{i,0}-a_{0,0}$和$y_{i}=(-1)^{i+1}a_{0,i}$,即$a_{i,j}=(-1)^{i+j}(B_{i,j}+x_{i}-y_{j})$

    同时,条件考虑对$i+j$奇偶性分类讨论,即:

    1.若$i+j$为偶数,则$-B_{i,j}le x_{i}-y_{j}le V-B_{i,j}$

    2.若$i+j$为奇数,则$B_{i,j}le y_{j}-x_{i}le V+B_{i,j}$

    对$x_{i}$和$y_{i}$这$n+m+2$个变量求差分约束即可,具体来说令$d_{i}$表示第$i$个变量的值,限制都可以转换为$d_{i}le d_{j}+x$,那么连边$(i,j,x)$后求最短路即满足此性质

    由于有负权,需要spfa,最坏时间复杂度为$o(T(n+m)^{3})$

    求出$x_{i}$和$y_{i}$后,即有$a_{i,j}=(-1)^{i+j}(B_{i,j}+x_{i}-y_{j})$,输出即可

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 605
     4 #define V 1000000
     5 #define ll long long
     6 struct Edge{
     7     int nex,to;
     8     ll len;
     9 }edge[N*N];
    10 queue<int>q;
    11 int E,t,n,m,head[N],vis[N],sum[N];
    12 ll d[N],b[N][N];
    13 void add(int x,int y,ll z){
    14     edge[E].nex=head[x];
    15     edge[E].to=y;
    16     edge[E].len=z;
    17     head[x]=E++;
    18 }
    19 bool spfa(){
    20     memset(d,0x3f,sizeof(d));
    21     memset(vis,0,sizeof(vis));
    22     memset(sum,0,sizeof(sum));
    23     d[0]=0;
    24     q.push(0);
    25     vis[0]=1;
    26     while (!q.empty()){
    27         int k=q.front();
    28         q.pop();
    29         for(int i=head[k];i!=-1;i=edge[i].nex)
    30             if (d[edge[i].to]>d[k]+edge[i].len){
    31                 d[edge[i].to]=d[k]+edge[i].len;
    32                 if (!vis[edge[i].to]){
    33                     q.push(edge[i].to);
    34                     vis[edge[i].to]=1;
    35                 }
    36                 if (++sum[edge[i].to]>n+m)return 0;
    37             }
    38         vis[k]=0;
    39     }
    40     return 1;
    41 }
    42 int main(){
    43     scanf("%d",&t);
    44     while (t--){
    45         scanf("%d%d",&n,&m);
    46         n--,m--;
    47         E=0;
    48         memset(head,-1,sizeof(head));
    49         for(int i=1;i<=n;i++)
    50             for(int j=1;j<=m;j++){
    51                 scanf("%lld",&b[i][j]);
    52                 if ((i+j)&1)b[i][j]*=-1;
    53                 b[i][j]+=b[i-1][j]+b[i][j-1]-b[i-1][j-1];
    54             }
    55         for(int i=0;i<=n;i++)
    56             for(int j=0;j<=m;j++)
    57                 if ((i+j)&1){
    58                     add(i,j+n+1,V+b[i][j]);
    59                     add(j+n+1,i,-b[i][j]);
    60                 }
    61                 else{
    62                     add(j+n+1,i,V-b[i][j]);
    63                     add(i,j+n+1,b[i][j]);
    64                 }
    65         if (!spfa()){
    66             printf("NO
    ");
    67             continue;
    68         }
    69         printf("YES
    ");
    70         for(int i=0;i<=n;i++){
    71             for(int j=0;j<=m;j++)
    72                 if ((i+j)&1)printf("%lld ",d[j+n+1]-d[i]-b[i][j]);
    73                 else printf("%lld ",b[i][j]+d[i]-d[j+n+1]);
    74             printf("
    ");
    75         }
    76     }
    77 }
    View Code
  • 相关阅读:
    微信接口开发之高级篇系列【微信权限封装类WechatAuth】
    微信接口开发之高级篇系列【用户分组接口和生成带参数的二维码】
    微信接口开发之高级篇系列【网页授权获取用户基本信息】
    微信接口开发之高级篇系列【微信JS-SDK】
    微信接口开发之高级篇系列【网页授权详细说明【提供测试账号使用】】
    微信接口开发之高级篇系列【网页授权接口】
    历史SQL语句之一
    盘点2019 | 金融科技发展大事件~
    FinTech终于被正名!央行印发金融科技发展规划
    安装配置开源的laravel项目到本地环境
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/14666585.html
Copyright © 2011-2022 走看看