2021.7.20 义乌模拟赛 T3 压位
那个bitset做法是真的屑所以我们考虑更优秀的做法。
考虑分治。
对于一个轴分治,对于两个点在分治线两边的就一定会经过中轴线,我们只要预处理出每个点到中轴线上每个点的连通性然后看看是否在中轴线上有一个点两点均可达。
然后分治下去即可,时间复杂度\(O(\frac{n^3logn}{w})\),但是并没有代码。
code:
#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define re register
#define ll long long
#define db double
#define N 500
#define M 1000000
#define mod 1000000007
#define eps (1e-7)
#define U unsigned int
#define it iterator
#define Gc() getchar()
#define Me(x,y) memset(x,y,sizeof(x))
using namespace std;
I void read(int &x){char s=Gc();x=0;while(s<'0'||s>'9') s=Gc();while(s>='0'&&s<='9') x=x*10+s-48,s=Gc();}
int n,m,k,now,last,nx,ny,mx,my,A[N+5][N+5],Ans[M+5];bitset<N+5> F[2][N+5][N+5];char c;
struct ques{int x,y,id;}tmp;vector<ques> Q[N+5][N+5];
int main(){
freopen("c.in","r",stdin);freopen("c.out","w",stdout);
re int i,j,h;scanf("%d%d%d",&n,&m,&k);for(i=1;i<=n;i++)for(j=1;j<=m;j++){
c=Gc();while(c<'0'||c>'9') c=Gc();A[i][j]=c-'0';
}for(i=1;i<=k;i++) read(nx),read(mx),read(ny),read(my),Q[nx][ny].push_back((ques){mx,my,i});
for(i=n;i;i--){
now=i&1;last=now^1;for(j=m;j;j--){
if(A[i][j]){for(h=i;h<=m;h++) F[now][j][h]=0;continue;}for(h=i;h<=m;h++) F[now][j][h]=F[last][j][h]|F[now][j+1][h];F[now][j][i][j]=1;
for(h=0;h<Q[i][j].size();h++) tmp=Q[i][j][h],Ans[tmp.id]=F[now][j][tmp.x][tmp.y];
}
}for(i=1;i<=k;i++) puts(Ans[i]?"Yes":"No");
}