洛谷 P5542 Painting the barn(二维差分 模板)

23 篇文章 0 订阅

题目大意:

小明对着墙壁画矩形,问小明画的矩形里面重叠k次的区域面积是多大。

解题思路:

首先,我们可以想到对画的一片区域进行+1操作,最后扫描一遍画的区域,若某个点的和为k我们就记录下来。

首先,我们可以试一下naive的+1,发现复杂多太高。这时候引入一个新结构叫做二维差分,二维差分再配合二维前缀和就可以达到O(n^2)的更新一片区域。关于二维差分,这里有一个解释:

https://www.cnblogs.com/LMCC1108/p/10753451.html

二维差分的公式是:假若我们想对(x1,y1)到(x2,y2)的区域进行+val操作。我们可以:

\\gra[x1][y1]+=val\\ gra[x2][y2+1]-=val\\ gra[x2+1][y1]]-=val\\ gra[x2+1][y2+1]+=val\\

 

其中gra是棋盘。为什么可以这样呢?简要来说,就是通过引入+val 和-val的标签后,在计算二位前缀和时可以达到只对某个区域+val的操作。大家可以试着动手算算。二维前缀和的公式是:

gra[x][y-1]+gra[x-1][y]-gra[x-1][y-1]+gra[x][y]

 

但注意在边界时,有些数组越界的项我们是需要去掉的。

AC代码:

#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e3+10;
int main(){
	int n,k;cin>>n>>k;
	vector<vector<int>> chess(MAXN,vector<int>(MAXN,0));
	for(int i=0;i<n;i++){
		int x1,y1,x2,y2;cin>>x1>>y1>>x2>>y2;
		x2-=1;y2-=1;
		chess[x1][y1]+=1;
		chess[x1][y2+1]-=1;
		chess[x2+1][y1]-=1;
		chess[x2+1][y2+1]+=1;
	}
	int ans=0;
	for(int x=0;x<MAXN;x++)
		for(int y=0;y<MAXN;y++){
			int ret=chess[x][y];
			if(x>=1)ret+=chess[x-1][y];
			if(y>=1)ret+=chess[x][y-1];
			if(x>=1 && y>=1)ret-=chess[x-1][y-1];
			chess[x][y]=ret;
			if(ret==k)ans++;
		}
	cout<<ans<<endl;
	return 0;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值