1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
| #include<bits/stdc++.h> using namespace std; #define int long long inline int read(){int x=0,f=1;char ch=getchar(); while(ch<'0'|| ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;} #define Z(x) (x)*(x) #define pb push_back
#define N 310
struct node { int top, l, r; }; int n, m, i, j, k, T; int ans, S[N][N], f[N][N], g[N][N], h[N][N]; int a[N], b[N], c[N], e[N], p[N], l, r, sum; int bin[N*N*2], mx[N], mnX[N*N], mxX[N*N], mnY[N*N], mxY[N*N]; int vis[N][N], tot, flg[N*N]; int dx[4]={0, 0, 1, -1}; int dy[4]={1, -1, 0, 0}; char s[N][N]; vector<node>G[N];
void dfs(int x, int y) { vis[x][y]=1; mnX[tot]=min(mnX[tot], x); mxX[tot]=max(mxX[tot], x); mnY[tot]=min(mnY[tot], y); mxY[tot]=max(mxY[tot], y); if(x==1 || y==1 || x==n || y==m) flg[tot]=1; for(int k=0; k<4; ++k) { int newx=x+dx[k], newy=y+dy[k]; if(newx<1 || newy<1 || newx>n || newy>m) continue; if(vis[newx][newy]) continue; if(s[newx][newy]!='0') continue; dfs(newx, newy); } }
signed main() {
freopen("village.in", "r", stdin); freopen("village.out", "w", stdout);
memset(mnX, 0x3f, sizeof(mnX)); memset(mnY, 0x3f, sizeof(mnY)); n=read(); m=read(); for(i=1; i<=n; ++i) scanf("%s", s[i]+1); for(i=1; i<=n; ++i) for(j=1; j<=m; ++j) if(s[i][j]=='0' && !vis[i][j]) ++tot, dfs(i, j); for(i=1; i<=tot; ++i) { if(flg[i]) continue;
G[mxX[i]+1].pb({mnX[i]-1, mnY[i], mxY[i]}); } for(i=1; i<=n; ++i) for(j=1; j<=m; ++j) s[i][j]-='0';
for(j=1; j<=m; ++j) for(i=1; i<=n; ++i) { f[i][j]=f[i-1][j]; if(s[i][j] && s[i-1][j]) ++f[i][j]; g[i][j]=g[i-1][j]; if(s[i][j] && s[i][j+1]) ++g[i][j]; h[i][j]=h[i-1][j]; if(s[i][j] && s[i-1][j] && s[i][j+1] && s[i-1][j+1]) ++h[i][j]; S[i][j]=S[i-1][j]; if(s[i][j]) ++S[i][j]; }
for(l=1; l<=n; ++l) { memset(mx, 0, sizeof(mx)); for(r=l; r<=n; ++r) { for(auto t : G[r]) if(t.top>=l) { mx[t.r+1]=max(mx[t.r+1], t.l); } for(i=1; i<=m; ++i) { p[i]=S[r][i]-S[l-1][i]; a[i]=f[r][i]-f[l][i]; b[i]=g[r][i]-g[l-1][i]; c[i]=h[r][i]-h[l][i]; e[i]=p[i]-a[i]-b[i]+c[i]; e[i]+=e[i-1]; }
bin[N*N]++; j=0; for(i=1; i<=m; ++i) { while(j+1<mx[i]) bin[e[j]+N*N]--, ++j;
k=e[i-1]+p[i]-a[i]-1; ans+=bin[k+N*N]; bin[e[i]+N*N]++; } while(j<=m) bin[e[j]+N*N]--, ++j;
} } printf("%lld", ans); return 0; }
|