[CF869E]The Untended Antiquity

The Untended Antiquity

题解

好水的题呀

由于没有矩形相交,任意两个矩形只存在包含与相离两种关系,由于要求的是两个点是否在同一矩阵中,我们可以对其进行染色,比较两点是否被染成同一颜色。

由于n,m\leq 2500O\left(n^2 q\right )的暴力染色明显会T,可以考虑通过二维树状数组进行区间修改,将复杂度降到O\left(qlog_{n}^2 \right )

但是存在包含的关系,同一点可能被多个矩形覆盖,而最后计算的应为面积最小的那个矩形,所以可以考虑离散化,由于在同一矩形中的两点所被覆盖的矩形应该是相同的,所以可以将其加起来判断。

源码

 

#include<bits/stdc++.h>
using namespace std;
#define MAXN 2505
#define lowbit(x) (x&-x)
const int INF=0x7f7f7f7f;
const int mo=1e9+7;
const int hs=233;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<LL,LL> pii;
int n,m,q;
LL tr[MAXN][MAXN];
void updata(int x,int y,int aw){
	for(int i=x;i<=n;i+=lowbit(i))
		for(int j=y;j<=m;j+=lowbit(j))
			tr[i][j]+=aw;
}
LL query(int x,int y){
	LL res=0;
	for(int i=x;i;i-=lowbit(i))
		for(int j=y;j;j-=lowbit(j))
			res+=tr[i][j];
	return res;
}
int Hash(int sx,int sy,int ex,int ey){
	return sx+sy*hs+ex*hs*hs+ey*hs*hs*hs;
}
signed main(){
	scanf("%d %d %d",&n,&m,&q);
	for(int i=1;i<=q;i++){
		int opt,sx,sy,ex,ey;
		scanf("%d %d %d %d %d",&opt,&sx,&sy,&ex,&ey);
		if(opt==1){
			LL num=Hash(sx,sy,ex,ey);
			updata(sx,sy,num);
			updata(sx,ey+1,-num);
			updata(ex+1,sy,-num);
			updata(ex+1,ey+1,num);
		} 
		else if(opt==2){
			LL num=Hash(sx,sy,ex,ey);
			updata(sx,sy,-num);
			updata(sx,ey+1,num);
			updata(ex+1,sy,num);
			updata(ex+1,ey+1,-num);
		}
		else puts(query(sx,sy)==query(ex,ey)?"Yes":"No");
	}
	return 0;
}

谢谢!!!

posted @ 2020-08-16 10:50  StaroForgin  阅读(7)  评论(0)    收藏  举报  来源