*题解: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;
}

浙公网安备 33010602011771号