题意:
给一个矩阵,每次操作之前矩阵内所有数都会加 1 1 1,操作有如下三种:
- 把一行的数全部改为 0 0 0
- 把一列的数全部改为 0 0 0
- 询问在可以走向所有大小不超过 k k k的方块时,从一个点能否到另一个点,如果可以求出最短路。
把每次加一操作都可以当做没有操作,用时间轴来表示,设上次某一行操作的时间为 t t t,如果现在时间为 t i m e time time,那么对于一个询问的 k k k,如果 t i m e − t < = k time-t<=k time−t<=k那么这一行就是可以走的。
列同理。
那么在网格图上的最短路怎么计算呢?
考虑网格图上最短路有哪几种可能性,分类讨论一下就可以了。 - 一个点的行是可以通行的,并且另一个点的列可以通行或者反过来。那么答案即为两点间曼哈顿距离。
- 两个点的行都是可以通行的,并且这两行之间有列是可以通行的,就可以算出来答案。列同理。
- 两个点之间的所有行都是可以通行的或者列都是可以通行的,这种情况答案也是两点曼哈顿距离。
接下来用什么维护呢?
单点修改?区间查询最值? ⟶ \longrightarrow ⟶线段树。
拆开行列造两颗线段树维护即可。
c o d e : code: code:
#include <bits/stdc++.h>
#define regi register int
#define ls (now<<1)
#define rs (now<<1|1)
int n,m,q;
int timeset;
int hh[100001],ll[100001];
inline int read(){
int r=0,w=0,c;
for(;!isdigit(c=getchar());r=c);
for(w=c^48;isdigit(c=getchar());w=w*10+(c^48))