任务统计
工作日五道题(1/5)
出题人在哪?出来我把你打一顿!
这题说三角形的底边长度一定是奇数
但是数据是有偶数的
我从下午十点调试到晚上一点半
我现在只想把出题人打一顿
链接
https://vjudge.net/problem/UVA-1493
题解
首先一看到覆盖,就想到倒过来离线做
首先我可以枚举每一列
然后就是涂色问题了,一种很好的并查集做法就是把涂过色的区域并起来,维护这个区域的上下端点,每次就可以直接跳过这个区域,由于每个点只会被涂一次,所以花在涂色上的均摊时间为
O
(
n
m
)
O(nm)
O(nm)
总的复杂度是
O
(
n
m
+
q
n
)
O(nm+qn)
O(nm+qn)
代码
#include <bits/stdc++.h>
#define maxn 210
#define maxm 50010
#define sqr(x) ((x)*(x))
#define code(x,y) ((x)*M+(y))
using namespace std;
typedef long long ll;
ll N, M, Q, col[maxn*maxm], xc, yc, r, c, l, w, type, p[maxm][5], Xc[maxm], Yc[maxm];
char s[maxm][20];
ll read(ll x=0)
{
ll c, f=1;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-48;
return f*x;
}
struct ufset
{
ll f[maxn*maxm], up[maxn*maxm], down[maxn*maxm], done[maxn*maxm];
void init(ll n)
{
for(auto i=0;i<n;i++)f[i]=i, up[i]=down[i]=i%M, done[i]=false;
}
ll find(ll x){return x==f[x]?x:f[x]=find(f[x]);}
void merge(ll x, ll y)
{
auto fx=find(x), fy=find(y);
up[fy]=max(up[fx],up[fy]);
down[fy]=min(down[fx],down[fy]);
f[fx]=fy;
}
}ufs;
bool judge(ll x, ll y)
{
if(x<0 or x>=N or y<0 or y>=M)return false;
switch(type)
{
case 'D':
return abs(x-xc) + abs(y-yc) <= r;
case 'C':
return sqr(x-xc) + sqr(y-yc) <= sqr(r);
case 'R':
return xc<=x and x<=xc+l-1 and yc<=y and y<=yc+w-1;
case 'T':
return abs(x-xc) + abs(y-yc) <= (w-1>>1) and x>=xc;
}
}
void paint(ll id)
{
ll i, j;
xc=Xc[id], yc=Yc[id], type=s[id][0];
switch(type)
{
case 'D':
r=p[id][1], c=p[id][2];
break;
case 'C':
r=p[id][1], c=p[id][2];
break;
case 'R':
l=p[id][1], w=p[id][2], c=p[id][3];
break;
case 'T':
w=p[id][1], c=p[id][2];
break;
}
for(i=0;i<N;i++)
{
j=ufs.down[ ufs.find( code(i,yc) ) ];
while(judge(i,j))
{
if(ufs.done[ code(i,j) ]==false)
{
col[ code(i,j) ]=c;
ufs.done[ code(i,j) ]=true;
if(j>0 and ufs.done[ code(i,j-1) ] )ufs.merge( code(i,j) , code(i,j-1) );
if(j<M-1 and ufs.done[ code(i,j+1) ] )ufs.merge( code(i,j) , code(i,j+1) );
}
if(j==0)break;
j=ufs.down[ ufs.find( code(i,j-1) ) ];
}
j=ufs.up[ ufs.find( code(i,yc) )];
while(judge(i,j))
{
if(ufs.done[ code(i,j) ]==false)
{
col[ code(i,j) ]=c;
ufs.done[ code(i,j) ]=true;
if(j>0 and ufs.done[ code(i,j-1) ] )ufs.merge( code(i,j) , code(i,j-1) );
if(j<M-1 and ufs.done[ code(i,j+1) ] )ufs.merge( code(i,j) , code(i,j+1) );
}
if(j==M-1)break;
j=ufs.up[ ufs.find( code(i,j+1) ) ];
}
}
}
int main()
{
ll ans[10], i, j;
while( ~scanf("%lld%lld%lld",&N,&M,&Q) )
{
ufs.init(N*M);
for(i=1;i<=Q;i++)
{
scanf("%s",s[i]);
Xc[i]=read(), Yc[i]=read();
for(j=1;j<=(s[i][0]=='R'?3:2);j++)p[i][j]=read();
}
for(i=0;i<N*M;i++)col[i]=0;
for(i=Q;i;i--)paint(i);
memset(ans,0,sizeof(ans));
for(i=0;i<N*M;i++)ans[col[i]]++;
for(i=1;i<=9;i++)printf("%lld",ans[i]), putchar(i==9?10:32);
}
return 0;
}