1. 程式人生 > 其它 >2021.7.20 義烏模擬賽 T3 壓位

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");
}