版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhuxiyulu/article/details/78234738
/*
二维树状数组+Hash
题意:
给一个地图(n,m) 三种操作:
1,在以(r1,c1)、(r2,c2)为对角的矩形四条边上添加障碍
2,消除以(r1,c1)、(r2,c2)为对角的矩形四条边上的障碍
3,判断(r1,c1)到(r2,c2)是否存在一条路径,不经过障碍
利用二维树状数组进行块更新,每次添加障碍时,用一个Hash值
如果两个点之间的Hash值是相同的,说明可以有路径不经过障碍
*/
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
typedef long long LL;
const int mod=10037;//用于Hash
const int maxn=2505;
map<pair<pair<int,int>,pair<int,int> >,LL>mp;//矩形的Hash值
int n,m,q;
LL tree[maxn][maxn];
int t,r1,c1,r2,c2;
//二维树状数组
int lowbit(int i)
{
return i&(-i);
}
void add(int l,int r,LL v)
{
for(int i=l;i<=n;i+=lowbit(i))
{
for(int j=r;j<=m;j+=lowbit(j))
{
tree[i][j]+=v;
}
}
}
LL get(int l,int r)
{
LL ans=0;
for(int i=l;i>=1;i-=lowbit(i))
{
for(int j=r;j>=1;j-=lowbit(j))
{
ans+=tree[i][j];
}
}
return ans;
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&q))
{
mp.clear();
LL Hash=1;//Hash值
memset(tree,0,sizeof(tree));
for(int i=0;i<q;i++)
{
scanf("%d%d%d%d%d",&t,&r1,&c1,&r2,&c2);
if(t==1)
{
Hash*=mod;//保证每次添加障碍时,Hash值都不同
mp[make_pair(make_pair(r1,c1),make_pair(r2,c2))]=Hash;//记录这个Hash值
//题目保证障碍没有公共点
add(r1,c1,Hash);
add(r2+1,c2+1,Hash);
add(r1,c2+1,-Hash);
add(r2+1,c1,-Hash);
}
else if(t==2)
{
LL cnt=mp[make_pair(make_pair(r1,c1),make_pair(r2,c2))];
add(r1,c1,-cnt);
add(r2+1,c2+1,-cnt);
add(r1,c2+1,cnt);
add(r2+1,c1,cnt);
}
else if(t==3)
{
LL ans1=get(r1,c1);//获取此时的Hash值
LL ans2=get(r2,c2);
if(ans1==ans2)
{
printf("Yes\n");
}
else
{
printf("No\n");
}
}
}
}
return 0;
}