Problem:
Score : 1500 points

Problem Statement

Problem F and F2 are the same problem, but with different constraints and time limits.

We have a board divided into N horizontal rows and N vertical columns of square cells.
The cell at the i-th row from the top and the j-th column from the left is called Cell (i,j).
Each cell is either empty or occupied by an obstacle.
Also, each empty cell has a digit written on it.
If A_{i,j}= 1, 2, ..., or 9, Cell (i,j) is empty and the digit A_{i,j} is written on it.
If A_{i,j}= #, Cell (i,j) is occupied by an obstacle.

Cell Y is reachable from cell X when the following conditions are all met:

Cells X and Y are different.

Cells X and Y are both empty.

One can reach from Cell X to Cell Y by repeatedly moving right or down to an adjacent empty cell.

Consider all pairs of cells (X,Y) such that cell Y is reachable from cell X.
Find the sum of the products of the digits written on cell X and cell Y for all of those pairs.

Constraints

1 \leq N \leq 1500

A_{i,j} is one of the following characters: 1, 2, ... 9 and #.

Input

Input is given from Standard Input in the following format:

N
A_{1,1}A_{1,2}...A_{1,N}
A_{2,1}A_{2,2}...A_{2,N}
:
A_{N,1}A_{N,2}...A_{N,N}

Output

Print the sum of the products of the digits written on cell X and cell Y for all pairs (X,Y) such that cell Y is reachable from cell X.

Sample Input 1

2
11
11

Sample Output 1

5

There are five pairs of cells (X,Y) such that cell Y is reachable from cell X, as follows:

X=(1,1), Y=(1,2)

X=(1,1), Y=(2,1)

X=(1,1), Y=(2,2)

X=(1,2), Y=(2,2)

X=(2,1), Y=(2,2)

The product of the digits written on cell X and cell Y is 1 for all of those pairs, so the answer is 5.

Sample Input 2

4
1111
11#1
1#11
1111

Sample Output 2

47

Sample Input 3

10
76##63##3#
8445669721
75#9542133
3#285##445
749632##89
2458##9515
5952578#77
1#3#44196#
4355#99#1#
#298#63587

Sample Output 3

36065

Sample Input 4

10
4177143673
7#########
5#1716155#
6#4#####5#
2#3#597#6#
6#9#8#3#5#
5#2#899#9#
1#6#####6#
6#5359657#
5#########

Sample Output 4

6525

Solution in C (GCC 5.4.1) (judge verdict: Runtime Error)

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define L 50
#define GET(x,y) *(map+((y-1)*(n+1))+(x-1))
#define GETANS(x,y,xx,yy) GETANS2((x-1),(y-1),(xx),(yy))
#define GETANS2(x,y,xx,yy) *(ansmap  + (yy*n*n*L)+(xx*n*n)+(y*n)+x  )
#define GETANS2(x,y,xx,yy) *(ansmap  + (yy*n*n*L)+(xx*n*n)+(y*n)+x  )
#define NUM(x,y) ((GET(x,y))-'0')

int n;
char* map;
char* ansmap;

int setHash(int Xx,int Xy,int Yx,int Yy, int ans)
{
  if( L <= (Yx-Xx) ) return 0;
  if( L <= (Yy-Xy) ) return 0;
  // 0:unknown 1:ok -1:ng
  GETANS(Xx,Xy,Yx-Xx,Yy-Xy) = ans;
  return 0;
}
  
int getHash(int Xx,int Xy,int Yx,int Yy)
{
  if( L <= (Yx-Xx) ) return 0;
  if( L <= (Yy-Xy) ) return 0;
//  fprintf(stderr,"%d,%d,%d,%d/",Xx,Xy,Yx-Xx,Yy-Xy);
  return GETANS(Xx,Xy,Yx-Xx,Yy-Xy);
}

int isOK(int Xx,int Xy,int Yx,int Yy)
{
  int ans;
  if( (Xx==Yx)&&(Xy==Yy) ) return 1;
  if(Xx>Yx) return 0; 
  if(Xy>Yy) return 0; 
  ans = getHash(Xx,Xy,Yx,Yy);
  if ( ans != 0 )
  {
    if(ans>0) return 1;
    return 0;
  }
  if( '#' == GET(Xx, Xy) ){ 
    setHash(Xx,Xy,Yx,Yy,-1);
    return 0;
  }
  if( isOK(Xx+1, Xy, Yx, Yy) ) {
    setHash(Xx,Xy,Yx,Yy,1);
    return 1;
  }
  if( isOK(Xx, Xy+1, Yx, Yy) ) {
    setHash(Xx,Xy,Yx,Yy,1);
    return 1;
  }
  setHash(Xx,Xy,Yx,Yy,-1);
  return 0;
}

int calc(int Xx,int Xy,int Yx,int Yy)
{
  int ok=isOK(Xx,Xy,Yx,Yy);
  if(0==ok) return 0;
  return ok*NUM(Xx,Xy)*NUM(Yx,Yy);
}

int main(void)
{
  int i;
  int sum=0;
  int Xx,Xy,Yx,Yy;
  scanf("%d",&n); 
//  printf ("%d\n",n);
  map = malloc((n+1)*(n+1));
  ansmap = calloc(n*n*50*50,1);

  for(i=0;i<n;i++)
    scanf("%s",(map+(n+1)*i)); 
//  for(i=0;i<n;i++)
//    printf("%s\n",(map+(n+1)*i));

  for(Xx=1;Xx<=n;Xx++)
  {
    for(Xy=1;Xy<=n;Xy++)
    {
      if( '#' == GET(Xx, Xy) ) continue;
      for(Yx=Xx;Yx<=n;Yx++)
      {
        for(Yy=Xy;Yy<=n;Yy++)
        {
          if( (Xx>=Yx) && (Xy>=Yy) ) continue;
          if( '#' == GET(Yx, Yy) )
          {
            if(Xx==Yx)break; 
            continue;
          }
          sum += calc(Xx,Xy,Yx,Yy);
        }
      }      
    }
  }
  printf( "%d\n", sum );
//  fprintf(stderr,"clock = %u\n",clock());
  return 0;
}