Official

F - Yet Another Grid Task Editorial by en_translator


First of all, we will try to simplify the input.
If a square \((i,j)\) is black in the input, then squares \((i+1,j)\) and \((i+1,j+1)\) in the resulting beautiful grid must be black too.
We will now modify the input according to this conditions. The following example in the left is modified to the right.

  ....#.      ....#.
  ......      ....##
  .#....  ->  .#..##
  ......      .##.##
  ......      .#####

We can see that the resulting grid is always beautiful.
This can be understood by trying this modification for several grids.

After all, what is a beautiful grid?
A grid is beautiful if and only if the following condition is satisfied.

  • For each \(c\), consider sorting squares \((i,j)\) such that \(i-j=c\) in ascending order of \(i\).
    • Here, the first several (possibly zero) squares are white, and the remaining are black.
    • \(L = (L_{-M+1},L_{-M+2},\dots,L_{N-1})\) is broadly monotonically decreasing, where \(L_c\) is the smallest \(j\) of a black square (corresponding to the leftmost one).

Although it is a bit difficult to understand on the text, but you can imagine inspecting the squares in the diagonal direction; when the diagonal line is moved from top to bottom, the boundary between the black and white squares shifts from right to left.
Now let us take into account the originally black squares, and consider solving it with a dynamic programming (DP).

For \(c = -M+1, -M+2 , \dots, N-1\) in this order, consider the DP table:
\(dp[c][j] = \) (the number of grids on which, when the diagonal scanning line is at \(i-j=c\), square \((j+c,j)\) and those in its right are painted black).

For convenience, we assume that the grid is extended indefinitely to the right and down, and those squares with \(i \ge N+1\) or \(j \ge M+1\) are all painted black. This does not change the answer. Also, for convenience, we initialize as \(dp[-M][M+1]=1\) and \(dp[-M][j]=0\).

  • First, let \(dp[c][j] = \sum^{M+1}_{k=j} dp[c-1][k]\). This can be found as a cumulative sum in a total of \(O(M)\) time over all \(j\).
  • Next, if square \((j+c,j)\) does not absent (i.e. \(j+c \le 0\)), let \(dp[c][j]=0\).
  • Finally, if square \((i,j)\) is black in the resulting grid, let \(dp[c][j+1]=0\).

The answer is \(\sum^{M+1}_{j=1} dp[N-1][j]\).
This way, the problem can be solved in a total of \(O(NM)\) time.

Sample code (C++):

#include<bits/stdc++.h>
#define mod 998244353

using namespace std;

int main(){
  long long n,m;
  cin >> n >> m;
  vector<string> s(n);
  for(auto &nx : s){cin >> nx;}

  for(int i=0;i<n;i++){
    for(int j=0;j<m;j++){
      if(s[i][j]=='#'){
        if(i!=(n-1)){s[i+1][j]='#';}
        if(i!=(n-1) && j!=(m-1)){s[i+1][j+1]='#';}
      }
    }
  }
  vector<long long> dp(m+1,0);
  dp[m]=1;
  for(int c=-m+1;c<=n-1;c++){
    for(int j=m-1;j>=0;j--){
      dp[j]+=dp[j+1];
      dp[j]%=mod;
    }
    for(int j=0;j<m;j++){
      int i=j+c;
      if(i<0){dp[j]=0;}
      else if(i>=n || s[i][j]=='#'){dp[j+1]=0;}
    }
  }
  long long res=0;
  for(auto &nx : dp){res+=nx;res%=mod;}
  cout << res << "\n";
  return 0;
}

posted:
last update: