题解 CF232E 【Quick Tortoise】

   日期:2020-10-30     浏览:94    评论:0    
核心提示:题解 - CF232E\mathrm{CF232E}CF232E题目意思题目传送门给你一张 n×mn\times mn×m 的图。 QQQ 次询问 (x,y,x1,y1)(x,y,x_1,y_1)(x,y,x1​,y1​) 问你能否从 (x,y)∼(x1,y1)(x,y)\sim(x_1,y_1)(x,y)∼(x1​,y1​)n,m≤500,Q≤6e5n,m\leq 500,Q\leq 6e5n,m≤500,Q≤6e5Sol\mathrm{Sol}Sol分治 + dp\mathrm{dp}dp

题解 - C F 232 E \mathrm{CF232E} CF232E

题目意思

题目传送门

给你一张 n × m n\times m n×m 的图。 Q Q Q 次询问 ( x , y , x 1 , y 1 ) (x,y,x_1,y_1) (x,y,x1,y1) 问你能否从 ( x , y ) ∼ ( x 1 , y 1 ) (x,y)\sim(x_1,y_1) (x,y)(x1,y1)

n , m ≤ 500 , Q ≤ 6 e 5 n,m\leq 500,Q\leq 6e5 n,m500,Q6e5

S o l \mathrm{Sol} Sol

分治 + d p \mathrm{dp} dp + b i t s e t \mathrm{bitset} bitset 做法

我们考虑离线做。

考虑如何判定能走到,我们对于每一行 l l l f i , j , k f_{i,j,k} fi,j,k 表示哪些 ( i , j ) ( i ∈ [ 1 , l ] ) (i,j)(i∈[1,l]) (i,j)(i[1,l]) 能够走到 ( l , k ) (l,k) (l,k)

同时设 g i , j , k g_{i,j,k} gi,j,k 哪些 ( i , j ) ( i ∈ [ l , n ] ) (i,j)(i∈[l,n]) (i,j)(i[l,n]) 能够走到 ( l , k ) (l,k) (l,k)。转移很简单

我们考虑分治来优化这个枚举 l l l 的过程。我们以 x x x 坐标进行分治,每次分治一边做掉一对起点终点在两端的询问。对于那些全部在一段的询问继续分治即可。

以及我们可以把 dp 用 b i t s e t \mathrm{bitset} bitset 来优化,时间复杂度 O ( log ⁡ n × n m 2 w ) O(\log n\times \frac{nm^2}{w}) O(logn×wnm2)

C o d e \mathrm{Code} Code

int n,m,Q,Ans[M];
char ch[N][N];
struct Node
{ 
	int x,y,fx,fy,id;
};
vector<Node> que;
bitset<N> f[N][N],g[N][N];
inline void solve(int l,int r,vector<Node> v) 
{ 
	if(l>r) return;
	int mid=l+r>>1,sz=(int)v.size();
	if(!sz) return;
	Dow(i,mid,l) Dow(j,m,1) 
	{ 
		f[i][j].reset(); 
		if(ch[i][j]!='#') 
		{ 
			if(i==mid) f[i][j][j]=1;
			else f[i][j]|=f[i+1][j];
			if(j<m) f[i][j]|=f[i][j+1];
		}
	}
	For(i,mid,r) For(j,1,m) 
	{ 
		g[i][j].reset();
		if(ch[i][j]!='#') 
		{ 
			if(i==mid) g[i][j][j]=1;
			else g[i][j]|=g[i-1][j];
			if(j!=1) g[i][j]|=g[i][j-1];
		}
	}
	vector<Node> L,R;
	for(Node i:v) 
	{ 
		if(i.fx<mid) L.pb(i); 
		else if(i.x>mid) R.pb(i);
		else Ans[i.id]|=((f[i.x][i.y]&g[i.fx][i.fy]).count()>=1); 
	}
	solve(l,mid-1,L),solve(mid+1,r,R);
}
int main()
{ 
	io.read(n),io.read(m);
	For(i,1,n) scanf("%s",ch[i]+1); 
	io.read(Q);
	For(i,1,Q)
	{ 
		int x,y,fx,fy;
		io.read(x),io.read(y),io.read(fx),io.read(fy);
		que.pb((Node){ x,y,fx,fy,i});
	}
	solve(1,n,que);
	For(i,1,Q) puts((Ans[i])?"Yes":"No");
	return 0;
}
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服