A sub-class of the three-dimensional rectangular Enumeration [count]

Description

There is a n m l n*m*l of a rectangular parallelepiped, each Location weights 0/1

For each of the position 1, this request includes the location and number of internal sub-wide rectangular parallelepiped 1.
n 60 n \ leq 60

Solution

We may wish to consider how the number of sub-two-dimensional rectangle.

If we enumerate every legal rectangular, inside +1 rectangle can be in the upper left, lower right corner of +1, -1 lower left upper right, do it again and you can get a two-dimensional prefix answer, three are similar.

If we can find each location were used as the upper left corner, lower right corner, lower left and upper right corner of each there have been many times, it can be directly counted.

The upper left corner, for example, pre-processing for each position down from the first 0 How many squares, each grid sweep from right to left, we found the lower right corner can be used to make a range of diminishing into something that can monotone stack to maintain, we only need to open the contribution, and the contribution of statistics monotonous stack to each location, this part can be done O ( n 2 ) O (n ^ 2)

Extended to three-dimensional, we can directly enumerate the first dimension of the upper and lower boundaries of the two-dimensional as described above can be done.
time complexity O ( n 4 ) O (n ^ 4)

Code

#include <bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fod(i,a,b) for(int i=a;i>=b;--i)
const int N=62;
using namespace std;
intn,m,l,t,ls[N][N];
LL bz[N][N][N],ct[N][N][N];
bool mp[N][N];
int d[N];
int main()
{
	cin>>n>>m>>l;
	fo(i,1,n)
	{
		fo(j,1,m) fo(k,1,l)
		{
			int x;
			scanf("%d",&x);
			bz[i][j][k]=1-x;
		}
	}	
	fo(i,1,n) 
	{
		memset(mp,0,sizeof(mp));
		fo(j,i,n)
		{
			fo(u,1,m) fo(v,1,l) mp[u][v]|=bz[j][u][v];
			//左上,+ -
			fod(u,m,1) 
			{
				d[0]=1;
				d[1]=l+1;
				LL s=0;	
				fod(v,l,1) 
				{
					ls[u][v]=(mp[u][v])?0:ls[u+1][v]+1;
					while(d[0]&&ls[u][v]<ls[u][d[d[0]]])
					{
						s-=(LL)d[d[0]-1]*(ls[u][d[d[0]]]-ls[u][d[d[0]-1]]);
						d[d[0]--]=0;
					}
					d[++d[0]]=v;
					s+=(LL)(d[d[0]-1])*(ls[u][d[d[0]]]-ls[u][d[d[0]-1]]);
					ct[i][u][v]+=s-(LL)v*ls[u][d[d[0]]];
					ct[j+1][u][v]-=s-(LL)v*ls[u][d[d[0]]];
				}
			}
			//左下 - +
			fo(u,1,m) 
			{
				d[0]=1;
				d[1]=l+1;
				LL s=0;	
				fod(v,l,1) 
				{
					ls[u][v]=(mp[u][v])?0:ls[u-1][v]+1;
					while(d[0]&&ls[u][v]<ls[u][d[d[0]]])
					{
						s-=(LL)d[d[0]-1]*(ls[u][d[d[0]]]-ls[u][d[d[0]-1]]);
						d[d[0]--]=0;
					}
					d[++d[0]]=v;
					s+=(LL)(d[d[0]-1])*(ls[u][d[d[0]]]-ls[u][d[d[0]-1]]);
					ct[i][u+1][v]-=s-(LL)v*ls[u][d[d[0]]];
					ct[j+1][u+1][v]+=s-(LL)v*ls[u][d[d[0]]];
				}
			}
			//右上 - +
			fod(u,m,1) 
			{
				d[0]=1;
				d[1]=0;
				LL s=0;	
				fo(v,1,l) 
				{
					ls[u][v]=(mp[u][v])?0:ls[u+1][v]+1;
					while(d[0]&&ls[u][v]<ls[u][d[d[0]]])
					{
						s+=(LL)d[d[0]-1]*(ls[u][d[d[0]]]-ls[u][d[d[0]-1]]);
						d[d[0]--]=0;
					}
					d[++d[0]]=v;
					s-=(LL)(d[d[0]-1])*(ls[u][d[d[0]]]-ls[u][d[d[0]-1]]);
					ct[i][u][v+1]-=(LL)v*ls[u][d[d[0]]]+s;
					ct[j+1][u][v+1]+=(LL)v*ls[u][d[d[0]]]+s;
				}
			}
			//右下 + -
			fo(u,1,m) 
			{
				d[0]=1;
				d[1]=0;
				LL s=0;	
				fo(v,1,l) 
				{
					ls[u][v]=(mp[u][v])?0:ls[u-1][v]+1;
					while(d[0]&&ls[u][v]<ls[u][d[d[0]]])
					{
						s+=(LL)d[d[0]-1]*(ls[u][d[d[0]]]-ls[u][d[d[0]-1]]);
						d[d[0]--]=0;
					}
					d[++d[0]]=v;
					s-=(LL)(d[d[0]-1])*(ls[u][d[d[0]]]-ls[u][d[d[0]-1]]);
					ct[i][u+1][v+1]+=(LL)v*ls[u][d[d[0]]]+s;
					ct[j+1][u+1][v+1]-=(LL)v*ls[u][d[d[0]]]+s;
				}
			}
		}
	}
	
	fo(i,1,n) fo(j,1,m) fo(k,1,l)
	{
		ct[i][j][k]+=ct[i-1][j][k]+ct[i][j-1][k]+ct[i][j][k-1]-ct[i-1][j-1][k]-ct[i][j-1][k-1]-ct[i-1][j][k-1]+ct[i-1][j-1][k-1];
		printf("%d\n",ct[i][j][k]);
	}
}

Guess you like

Origin blog.csdn.net/hzj1054689699/article/details/93737729