1. 程式人生 > >codeforces869EThe Untended Antiquity(二維樹狀陣列)

codeforces869EThe Untended Antiquity(二維樹狀陣列)

/*
二維樹狀陣列+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; }