此题可以用bitset或树状数组来编写,其中bitset代码短,速度慢——3354ms;树状数组要快很多——374ms。
此处发一下树状数组版代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll read(){
ll a=0,b=getchar(),c=1;
while(!isdigit(b))c=b=='-'?-1:1,b=getchar();
while(isdigit(b))a=a*10+b-'0',b=getchar();
return a*c;
}
const int N=3008;
struct node{
int x,y;
}t;
vector<node> d[N];
int n,m,a[N][N],b[N][N][2],c[N][N];
char s[N];
void add(int x,int y,int k){
while(x<N)c[x][y]+=k,x+=x&(-x);
}
int sum(int x,int y){
int res=0;
while(x>0)res+=c[x][y],x-=x&(-x);
return res;
}
int main(){
n=read(),m=read();
for(int i=1;i<=n;i++){
scanf("%s",s+1);
for(int j=1;j<=m;j++)
a[i][j]=s[j]=='z';
}
for(int i=1;i<=n;i++)
for(int j=m;j>0;j--)
if(a[i][j])b[i][j][0]=b[i][j+1][0]+1,b[i][j][1]=b[i-1][j+1][1]+1;
ll ans=0;
for(int i=1;i<=n;i++){
for(int j=m;j>0;j--)
if(a[i][j]){
add(i,j,1),t.x=i,t.y=j;
if(i+b[i][j][0]-1<N)d[i+b[i][j][0]-1].push_back(t);
ans+=sum(i,j)-sum(i-min(b[i][j][0],b[i][j][1]),j);
}
for(int j=0;j<d[i].size();j++)
add(d[i][j].x,d[i][j].y,-1);
}
printf("%lld",ans);
return 0;
}