![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) /**//*
题意:给出n*n的蛋糕 现要切蛋糕,同时询问点(x1,y1) (x2,y2)是否还连通
反过来做 用并查集即可
对于切割,要处理好!
color[i,j]=1表示格子[i,j]的右边缘被切
color[i,j]=2表示格子[i,j]的下边缘被切
一开始读入所有,全部先切割完(即染色)
然后两个for 对每个格子,向其右边缘、下边缘,看能不能合并
反过来做即可
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
http://acm.ustc.edu.cn/ustcoj/problem.php?id=1206
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1000,maxq=100000;
struct op
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
int op;
int x1,y1,x2,y2;
} p[maxq];
int n,q;
bool init()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
scanf("%d%d",&n,&q);
if(n==0&&q==0) return false;
for(int i=0;i<q;i++)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
char s[1024];
scanf("%s%d%d%d%d",s,&p[i].x1,&p[i].y1,&p[i].x2,&p[i].y2);
if(*s=='c') p[i].op=0; else p[i].op=1;
if(p[i].y1==p[i].y2&&p[i].x1>p[i].x2) swap(p[i].x1,p[i].x2);
else if(p[i].x1==p[i].x2&&p[i].y1>p[i].y2) swap(p[i].y1,p[i].y2);
}
return true;
}
int f[maxn*maxn],r[maxn*maxn];
int find(int u)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
if(f[u]==u) return u;
return f[u]=find(f[u]);
}
void combine(int u,int v)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
u=find(u);
v=find(v);
if(r[u]<r[v]) f[u]=v;
else if(r[u]>r[v]) f[v]=f[u];
else
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
f[u]=v;
r[v]++;
}
}
inline int adr(int i,int j,int n)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
return i*n+j;
}
void solve()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
static char b[maxn][maxn],ans[maxq];
memset(b,0,sizeof(b));
for(int i=0;i<q;i++)
if(p[i].op==0)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
if(p[i].y1==p[i].y2)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
int y=p[i].y1-1;
for(int j=p[i].x1;j<p[i].x2;j++) b[y][j]|=1;
}
else
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
int x=p[i].x1-1;
for(int j=p[i].y1;j<p[i].y2;j++) b[j][x]|=2;
}
}
memset(r,0,sizeof(r));
for(int i=0;i<n*n;i++) f[i]=i;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//枚举所有格子 向其右边缘、下边缘 看能不能合并
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
if(i<n-1&&(b[i][j]&1)==0) combine(adr(i,j,n),adr(i+1,j,n));
if(j<n-1&&(b[i][j]&2)==0) combine(adr(i,j,n),adr(i,j+1,n));
}
memset(ans,255,sizeof(ans));
for(int i=q-1;i>=0;i--)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
if(p[i].op==0)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
if(p[i].y1==p[i].y2)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
int y=p[i].y1-1;
for(int j=p[i].x1;j<p[i].x2;j++) combine(adr(y,j,n),adr(y+1,j,n));
}
else
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
int x=p[i].x1-1;
for(int j=p[i].y1;j<p[i].y2;j++) combine(adr(j,x,n),adr(j,x+1,n));
}
}
else
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
if(find(adr(p[i].y1-1,p[i].x1-1,n))==find(adr(p[i].y2-1,p[i].x2-1,n))) ans[i]=1; else ans[i]=0;
}
}
for(int i=0;i<q;i++)
if(ans[i]==0) puts("No");
else if(ans[i]==1) puts("Yes");
}
int main()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
//freopen("tb.in","r",stdin);
//freopen("tb.out","w",stdout);
while(init()) solve();
//fclose(stdin);
//fclose(stdout);
return 0;
}
|