*题解:CF869E The Untended Antiquity

题目链接

解析

首先需要观察到一个重要的性质:两个格子可达当且仅当包含它们的矩形集合相同。要判断集合是否相同,考虑和哈希,给每个矩形随机分配权值,并加到覆盖的每个格子上。于是我们需要矩形加,单点查,使用二维树状数组维护即可。

时间复杂度 \(O(q\log^2 n)\)

代码

#include <bits/stdc++.h>
#define ls(x) ((x) << 1)
#define rs(x) (((x) << 1) | 1)
#define mid ((l + r) >> 1)
using namespace std;
const int N = 2500 + 5;
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned ui;
mt19937 Rand(chrono::steady_clock::now().time_since_epoch().count());
ui b[N][N];
void add(int x,int y,ui k){
	for(;x < N;x += x & -x){
		int z = y;
		for(;z < N;z += z & -z){
			b[x][z] += k;
		}
	}
}
ui ask(int x,int y){
	ui res = 0;
	for(;x;x -= x & -x){
		int z = y;
		for(;z;z -= z & -z){
			res += b[x][z];
		}
	}
	return res;
}
void modi(int r1,int c1,int r2,int c2,ui k){
	add(r2 + 1,c2 + 1,k);
	add(r2 + 1,c1,-k);
	add(r1,c2 + 1,-k);
	add(r1,c1,k);
}
struct Mtx{
	int r1,c1,r2,c2;
	friend bool operator < (Mtx a,Mtx b){
		if(a.r1 != b.r1) return a.r1 < b.r1;
		if(a.c1 != b.c1) return a.c1 < b.c1;
		if(a.r2 != b.r2) return a.r2 < b.r2;
		return a.c2 < b.c2;
	}
};
map<Mtx,ui> mp;
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
//	freopen("in.txt","r",stdin);
//	freopen("out.txt","w",stdout); 
	int n,m,q;
	cin>>n>>m>>q;
	while(q--){
		int t,r1,c1,r2,c2;
		cin>>t>>r1>>c1>>r2>>c2;
		if(t == 1){
			mp[{r1,c1,r2,c2}] = Rand();
			modi(r1,c1,r2,c2,mp[{r1,c1,r2,c2}]);
		}else if(t == 2){
			modi(r1,c1,r2,c2,-mp[{r1,c1,r2,c2}]);
		}else{
			ui a1 = ask(r1,c1),a2 = ask(r2,c2);
			cout<<(a1 == a2 ? "Yes" : "No")<<'\n';
		}
	}
	return 0;
}
posted @ 2026-09-06 14:23  yutar  阅读(5)  评论(0)    收藏  举报