codeforces869EThe Untended Antiquity(二維樹狀陣列)
阿新 • • 發佈:2018-11-01
/*
二維樹狀陣列+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;
}