Codeforces 869E. The Untended Antiquity (二維Fenwick,Hash)
阿新 • • 發佈:2018-11-20
Codeforces 869E. The Untended Antiquity
題意:
在一張mxn的格子紙上,進行q次操作:
1,指定一個矩形將它用柵欄圍起來。
2,撤掉一個已有的柵欄。
3,詢問指定兩點之間是否連通(即能否從其中一點不翻越柵欄走到另一點)
思路:
對於操作1,將給定的矩形雜湊成一個數(可對點座標進行進位制雜湊),對整個矩形所覆蓋的點都累加上這個數;
對於操作2,則逆著把操作1的影響抵消掉;
對於操作3,看一下兩點的值是否相同(相同表示他們被相同的矩形們所覆蓋)。
至於每次矩形內的所有點的修改操作以及單點查值,使用二維樹狀陣列來維護,用到了差分思想,維護的是差分陣列,則單點查詢即求差分陣列的字首和。具體可見程式碼,在圖上畫一畫,不難理解
程式碼:
#include<bits/stdc++.h> #define de(x) cout<<#x<<" = "<<x<<"\n" #define dd(x) cout<<#x<<" = "<<x<<" " #define sz(x) int(x.size()) #define All(x) x.begin(),x.end() #define fi first #define se second #define pb push_back #define mp make_pair using namespace std; typedef long long ll; typedef long double ld; typedef pair<int,int> P; typedef priority_queue<int> BQ; typedef priority_queue<int,vector<int>,greater<int> > SQ; const int maxn=3e3+10,INF=0x3f3f3f3f; ll fw[maxn][maxn]; void add(int x,int y,ll c) { for (int i=x;i<maxn;i+=i&-i) for (int j=y;j<maxn;j+=j&-j) fw[i][j]+=c; } ll qry(int x,int y) { ll res=0; for (int i=x;i;i-=i&-i) for (int j=y;j;j-=j&-j) res+=fw[i][j]; return res; } ll seed=2333; inline ll Hash(int a,int b,int c,int d) { return a*seed*seed*seed+b*seed*seed+c*seed+d; } int main() { int n,m,q; cin>>n>>m>>q; for (int i=0;i<q;++i) { int op,x1,y1,x2,y2; scanf("%d%d%d%d%d",&op,&x1,&y1,&x2,&y2); if (op==3) { if (qry(x1,y1)==qry(x2,y2)) printf("Yes\n"); else printf("No\n"); } else { ll hs=Hash(x1,y1,x2,y2); if (op==2) hs=-hs; add(x1,y1,hs); add(x2+1,y2+1,hs); add(x1,y2+1,-hs); add(x2+1,y1,-hs); } } return 0; }