大概就是分治,每次从中线往两边走,用 bitset 判断,现在 wa5,求调/kel
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
const int mod=1e9+7;
#define inf 1e9
inline int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
const int N=505;
bitset<N>f[N][N];
int n,m,Q,Ans[maxn];
char S[N][N];
struct node{int x1,y1,x2,y2,id;}q[maxn],tmp[maxn];
inline void solve(int l,int r,int L,int R){
if(l>r||L>R)return;
int mid=(l+r)>>1;
for(int i=l;i<=r;i++)
for(int j=1;j<=m;j++)f[i][j].reset();
for(int i=m;i>=1;i--)
if(S[mid][i]!='#')f[mid][i][i]=1,f[mid][i]|=f[mid][i+1];
for(int i=mid-1;i>=l;i--)
for(int j=m;j>=1;j--)
if(S[i][j]!='#')f[i][j]=f[i+1][j]|f[i][j+1];
for(int i=mid+1;i<=r;i++)
for(int j=1;j<=m;j++)if(S[i][j]!='#'){
if(i==mid+1){if(S[mid][j]!='#')f[i][j][j]=1;f[i][j]|=f[i][j-1];}
else f[i][j]=f[i-1][j]|f[i][j-1];
}
int ql=L-1,qr=R+1;
for(int i=L;i<=R;i++){
if(q[i].x2<mid)tmp[++ql]=q[i];
else if(q[i].x1>mid)tmp[--qr]=q[i];
else Ans[q[i].id]=(f[q[i].x1][q[i].y1]&f[q[i].x2][q[i].y2]).any();
}
for(int i=L;i<=R;i++)q[i]=tmp[i];
solve(l,mid-1,L,ql);solve(mid+1,r,qr,R);
}
int main(){
n=read(),m=read();
for(int i=1;i<=n;i++)
scanf("%s",S[i]+1);
// for(int i=1;i<=n;i++,puts(""))
// for(int j=1;j<=m;j++)putchar(S[i][j]);
Q=read();
for(int i=1;i<=Q;i++)
q[i]=(node){read(),read(),read(),read(),i};
solve(1,n,1,Q);
for(int i=1;i<=Q;i++)
puts(Ans[i]?"Yes":"No");
return 0;
}