Lawn of the Dead

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Lawn of the Dead相关的知识,希望对你有一定的参考价值。

Lawn of the Dead

题意:

有一个N * M的方格,我们从(1,1)出发,只能向右走或者向下走,存在一些障碍,问有多少格子是我们所能到达的
2<=n,m,k<=1e5

题解:

所有的点减去不能到达的点的个数,就是可以到达的点的个数
有障碍的地方不能达到,而我们只能向右向下走,当某个点的左边和上边都是不可达时,该点就不可达,并会对自己的右边的点和下方的点造成影响
n,m,k<=1e5,空间很大但是地雷数目有限,我们可以从上往下逐行对每一行的地雷排序后处理,对于每个地雷,找到从自己的右上角点(x-1,y+1)开始从左往右的连续不可达区间的范围,那么x这行的这个范围也不可达,我们可以用线段树来实现区间的查询与维护。处理每一行,累加后用总点数减去即可


官方代码中,将可以到达的区域赋值1,每次找第x-1行区间内最最左侧的1,然后将第x行这段区间赋值为1,剩下0即为不可到达区域

代码:

md调了半天还是不对


2021/7/30 0:41
问题解决,现在代码对了,睡觉

#include<bits/stdc++.h>
#define debug(a,b) printf("%s = %d\\n",a,b);
#define ls (rt<<1)
#define rs ((rt<<1)|1)
typedef long long ll;
using namespace std;
//Fe~Jozky
const ll INF_ll=1e18;
const int INF_int=0x3f3f3f3f;
inline ll read(){
   ll s=0,w=1ll;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1ll;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10ll+((ch-'0')*1ll),ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
   return s*w;
}
const int maxn=3e5+9; 
int n,m,k;
vector<int>vec[maxn];
struct tree{
	int l,r;
	int lazy;
	int sum;
}tr[2][maxn];
void pushup(int op,int rt){
	tr[op][rt].sum=tr[op][ls].sum+tr[op][rs].sum;
}
void solve(int op,int rt,int val){
	tr[op][rt].sum=(tr[op][rt].r-tr[op][rt].l+1)*val;
	tr[op][rt].lazy=val;
}
void pushdown(int op,int rt){
	solve(op,ls,tr[op][rt].lazy);
	solve(op,rs,tr[op][rt].lazy);
	tr[op][rt].lazy=-1;
}
void build(int op,int rt,int l,int r){
	tr[op][rt].l=l;
	tr[op][rt].r=r;
	if(l==r){
		tr[op][rt].sum=0;
		tr[op][rt].lazy=-1;
		return ;
	}
	int mid=l+r>>1;
	build(op,ls,l,mid);
	build(op,rs,mid+1,r);
	pushup(op,rt);
}
void update(int op,int rt,int L,int R,int v){
	if(L>tr[op][rt].r||R<tr[op][rt].l)return ;
	if(L<=tr[op][rt].l&&tr[op][rt].r<=R){
		solve(op,rt,v);
		return ;
	}
	if(tr[op][rt].lazy!=-1)pushdown(op,rt);
	update(op,ls,L,R,v);
	update(op,rs,L,R,v);
	pushup(op,rt);
}
int query(int op,int rt,int L,int R){
	if(!tr[op][rt].sum)return INF_int;
	if(L>tr[op][rt].r||R<tr[op][rt].l)return INF_int;
	if(tr[op][rt].l==tr[op][rt].r)return tr[op][rt].l;
	if(tr[op][rt].lazy!=-1)
		pushdown(op,rt);
	if(L<=tr[op][rt].l&&tr[op][rt].r<=R){
		if(tr[op][ls].sum>0)return query(op,ls,L,R);
		else return query(op,rs,L,R);
	}
	
	return min(query(op,ls,L,R),query(op,rs,L,R));
}
void init(){
	for(int i=1;i<=n;i++)vec[i].clear();
	memset(tr,0,sizeof(tr));
}
int main()
{
	//freopen("1008.in","r",stdin);
	int t=read();
	while(t--){
		scanf("%d%d%d",&n,&m,&k);
		init();
		for(int i=1;i<=k;i++){
			int x,y;
			scanf("%d%d",&x,&y);
			vec[x].push_back(y);
		}
		build(0,1,1,m);
		build(1,1,1,m);
		update(1,1,1,1,1);
		int op=0;
		ll ans=0;
		for(int i=1;i<=n;i++){
			int L=0;
			sort(vec[i].begin(),vec[i].end());
			int pos;
			for(int y:vec[i]){
				
				if(y-1>=L+1)
				{
					pos=query(op^1,1,L+1,y-1);
					if(pos!=INF_int)
						update(op,1,pos,y-1,1);
				}
				L=y; 
			}
			if(L+1<=m){
				pos=query(op^1,1,L+1,m);
				if(pos!=INF_int)
					update(op,1,pos,m,1);
			}
			ans+=tr[op][1].sum;
			update(op^1,1,1,m,0);
			op^=1;
		}
		printf("%lld\\n",ans);
	}
	return 0;
}





官方代码:

#include<bits/stdc++.h>
using namespace std;
#define ls (x<<1)
#define rs (x<<1|1)
const int N = 1e5 + 5;
const int inf = 0x3f3f3f3f;
vector<int>e[N];
int tr[2][N << 2], lz[2][N << 2];

void push_down(int f, int x, int l, int r, int mid) {
	if (lz[f][x] == -1)return;
	tr[f][ls] = lz[f][x] * (mid - l + 1);
	tr[f][rs] = lz[f][x] * (r - mid);
	lz[f][ls] = lz[f][rs] = lz[f][x];
	lz[f][x] = -1;
}
void update(int f,int x, int l, int r, int L, int R, int v) {
	if (L <= l && R >= r) {
		tr[f][x] = (r - l + 1) * v;
		lz[f][x] = v;
		return;
	}
	int mid = (l + r) >> 1;
	push_down(f, x, l, r, mid);
	if (R <= mid)update(f, ls, l, mid, L, R, v);
	else if (L > mid)update(f, rs, mid + 1, r, L, R, v);
	else {
		update(f, ls, l, mid, L, mid, v);
		update(f, rs, mid + 1, r, mid + 1, R, v);
	}
	tr[f][x] = tr[f][ls] + tr[f][rs];
}
int query(int f, int x, int l, int r, int L, int R) {
	if (!tr[f][x])return inf;
	if (l == r)return l;
	int mid = l + r >> 1;
	push_down(f, x, l, r, mid);
	if (L <= l && R >= r) {
		if (tr[f][ls] > 0) return query(f, ls, l, mid, L, R);
		else return query(f, rs, mid + 1, r, L, R);
	}
	else {
		if (R <= mid)return query(f, ls, l, mid, L, R);
		else if (L > mid)return query(f, rs, mid + 1, r, L, R);
		else return min(query(f, ls, l, mid, L, mid), query(f, rs, mid + 1, r, mid + 1, R));
	}
}
int main() {
	int T;
	scanf("%d", &T);
	while (T--) {
		int n, m, k;
		scanf("%d %d %d", &n, &m, &k);
		for (int i = 1; i <= n; ++i)e[i].clear();
		for (int i = 1; i <= (m << 2); ++i) {
			tr[0][i] = tr[1][i] = 0;
			lz[0][i] = lz[1][i] = -1;
		}
		for (int i = 0; i < k; ++i) {
			int x, y;
			scanf("%d %d", &x, &y);
			e[x].push_back(y);
		}
		long long ans = 0;
		update(0, 1, 1, m, 1, 1, 1);
		for (int x = 1; x <= n; ++x) {
			int l = 0;
			sort(e[x].begin(), e[x].end());
			for (auto& y : e[x]) {
				if (y - 1 >= l + 1) {
					int pos = query((x & 1) ^ 1, 1, 1, m, l + 1, y - 1);
					if (pos != inf以上是关于Lawn of the Dead的主要内容,如果未能解决你的问题,请参考以下文章

HDOJ6992Lawn of the Dead(线段树×, 模拟大法好√)

台州 OJ 3847 Mowing the Lawn 线性DP 单调队列

Mowing the Lawn线性dp + 单调队列优化

P2627 [USACO11OPEN]Mowing the Lawn G (单调队列优化dp)

luogu P2627 [USACO11OPEN]Mowing the Lawn G 单调队列优化dp

detectron2报AttributeError: Attribute ‘evaluator_type‘ does not exist in the metadata of dataset(代码片段