题意
一个地图,然后三种操作
1.一个矩阵四周加上障碍
2.一个矩阵四周的障碍消除
3.问你两个点之间是否纯在一条路径不经过障碍
题解
想这题的时候一直就感觉是树状数组。。
然后一开始的想法是对于一个点,维护包含他的矩阵面积的最小值
于是一直没想到怎么撤销
看了题解才会做
我们可以给每一个矩阵一个hash值
然后将矩阵里面的点都加上这个数
如果是撤销障碍就减去
然后判断两个点是否连通就看一下他的数是多少
至于怎么维护这个矩阵加上,我们可以用一个类似差分的思想,然后用树状数组维护一下
就像下图:
然后对于一个点得到他的矩阵和就好了
CODE:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<map>
using namespace std;
typedef unsigned long long LL;
const int N=2505;
const LL MOD=10037;
map<pair<pair<int, int>, pair<int, int> >, LL>g;
int n,m,p;
LL f[N][N];
int lb (int x){return x&(-x);}
void change (int x,int y,LL z)
{
for (int u=x;u<=n;u+=lb(u))
for (int i=y;i<=m;i+=lb(i))
f[u][i]=f[u][i]+z;
}
LL get (int x,int y)
{
LL lalal=0;
for (int u=x;u>=1;u-=lb(u))
for (int i=y;i>=1;i-=lb(i))
lalal=lalal+f[u][i];
return lalal;
}
int main()
{
memset(f,0,sizeof(f));
scanf("%d%d%d",&n,&m,&p);
LL s=1;
for (int u=1;u<=p;u++)
{
int op,x1,y1,x2,y2;
scanf("%d%d%d%d%d",&op,&x1,&y1,&x2,&y2);
if (op==1)//加上
{
s=s*MOD;
g[make_pair(make_pair(x1,y1),make_pair(x2,y2))]=s;
change(x1,y1,s);
change(x1,y2+1,-s);
change(x2+1,y1,-s);
change(x2+1,y2+1,s);
}
if (op==2)
{
LL ooo=g[make_pair(make_pair(x1,y1),make_pair(x2,y2))];
change(x1,y1,-ooo);
change(x1,y2+1,ooo);
change(x2+1,y1,ooo);
change(x2+1,y2+1,-ooo);
}
if (op==3)
{
LL aa=get(x1,y1),bb=get(x2,y2);
if (aa==bb) printf("Yes\n");
else printf("No\n");
}
}
return 0;
}