http://acm.hdu.edu.cn/showproblem.php?pid=4056
题意:给n*m的格点 (n=200,m=5e5)
q次操作,每次按 四个几何图形 的面积去覆盖格点 ,每个图形带有一个颜色C (q=5e5,C=[1-9])
问最后q次操作完成后,每种颜色的格子有多少个,输出9个数
可以知道,颜色会覆盖,因此,从最后面开始处理,如果当前要涂色的格子未涂色,则这个格子最终必定是当前要涂的色,同理如果当前格子已经有色,则需要忽略。
现在问题是怎么处理涂色操作?
由于行很少,可以暴力按行涂色,也即把该几何图形要覆盖的每一行都遍历,对于每行,用并查集去维护一个 大小为M的列:
维护一个father数组,fa[x]指的是x这个位置起,到达下一个可被涂色的位置-1,
维护一个vis数组,vis[x]=1,表示该位置已经涂色,=0则未涂色
假如图形X在 第i行的涂色范围是第L列到第R列,则
l=max (l,0);
r=min(r,m-1);
int fx=find(l);
for (int i=r; i>=l;)
{
int fy=find(i);<span style="white-space:pre"> </span>//找到最左的可涂色位置
if (!vis[fy]) ans[col]++;<span style="white-space:pre"> </span>//可涂色
vis[fy]=1;<span style="white-space:pre"> </span>//标记已涂色
if (fx!=fy) fa[fy]=fx;<span style="white-space:pre"> </span>//更新 【最左可涂色位置】
i=fy-1;<span style="white-space:pre"> </span>//继续滑动
}
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
const double pi=acos(-1.0);
double eps=0.000001;
int fa[51234];
int vis[51234];
int find(int x)
{
if (fa[x]==x)
return x;
else return fa[x]=find(fa[x]);
}
struct node
{
char op[12];
int x,y,z,d;
int e;
node() {}
};
node tm[51234];
int ans[10];
int main()
{
int n,m,k;
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
memset(ans,0,sizeof ans);
for (int i=1; i<=k; i++)
{
scanf("%s%d%d%d%d",tm[i].op,&tm[i].x,&tm[i].y,&tm[i].z,&tm[i].d);
if (tm[i].op[0]=='R') scanf("%d",&tm[i].e);
}
for (int j=0; j<n; j++)
{
for (int i=0; i<=m; i++) fa[i]=i,vis[i]=0;
for (int i=k; i>=1; i--)
{
int l,r,col=tm[i].d;
if (tm[i].op[0]=='C')
{
int up=tm[i].x+tm[i].z;
int down=tm[i].x-tm[i].z;
if (!(j>=down&&j<=up ))continue;
int tmp=tm[i].z*tm[i].z-(tm[i].x-j)*(tm[i].x-j);
tmp=sqrt(tmp);
l=tm[i].y-tmp;
r=tm[i].y+tmp;
}
if (tm[i].op[0]=='D')
{
int up=tm[i].x+tm[i].z;
int down=tm[i].x-tm[i].z;
if (!(j>=down&&j<=up ))continue;
l=tm[i].z-abs(j-tm[i].x);
r=tm[i].y+l;
l=tm[i].y-l;
}
if (tm[i].op[0]=='R')
{
col=tm[i].e;
int up=tm[i].x+tm[i].z-1;
int down=tm[i].x;
if (!(j>=down&&j<=up ))continue;
l=tm[i].y;
r=tm[i].y+tm[i].d-1;
}
if (tm[i].op[0]=='T')
{
int up=tm[i].x+(tm[i].z+1)/2-1;
int down=tm[i].x;
if (!(j>=down&&j<=up ))continue;
int tmp=(tm[i].z-1)/2+(tm[i].x-j);
l=tm[i].y-tmp;
r=tm[i].y+tmp;
}
l=max (l,0);
r=min(r,m-1);
int fx=find(l);
for (int i=r; i>=l;)
{
int fy=find(i);
if (!vis[fy]) ans[col]++;
vis[fy]=1;
if (fx!=fy) fa[fy]=fx;
i=fy-1;
}
}
}
for (int i=1; i<=9; i++)
{
if (i>1) printf(" ");
printf("%d",ans[i]);
}
printf("\n");
}
return 0;
}