Codeforces 869E. The Untended Antiquity (二维Fenwick,Hash)

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;
}
posted @ 2018-11-20 22:48  __orange  阅读(260)  评论(0编辑  收藏  举报