(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦
Catalog
Problem:Portal传送门
原题目描述在最下面。
换一种描述就是,给你一个
1e9
1
e
9
的矩阵,有
n(200)
n
(
200
)
个点,问把这个矩阵分成的联通块的个数和联通块的面积。
Solution:
比赛时和比赛后真的时两个脑子。
先问你这么个问题,平面坐标轴上给你两个点
(x1,y1)
(
x
1
,
y
1
)
,
(x2,y2)
(
x
2
,
y
2
)
,问这两点组成的矩阵面积是多少?
中学生应该都知道答案是
|(x2−x1)×(y2−y1)|
|
(
x
2
−
x
1
)
×
(
y
2
−
y
1
)
|
。
那么这个题就很简单了,把所有坐标离散化一下,因为只有200个点。离散化预处理完后暴搜求联通块的个数,顺便给每个点编号,最后统一求面积。而求面积的方法不就是上面那个方法吗?
求出联通块后按每个点求面积贡献,点
(xi,yi)
(
x
i
,
y
i
)
的贡献应该是
(xi−xi−1)×(yi−yi−1)
(
x
i
−
x
i
−
1
)
×
(
y
i
−
y
i
−
1
)
。注意一下边界情况就好了。
注意一下就是答案要按升序输出。
AC_Code:
#include<bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
#define lowbit(x) (x&(-(x)))
#define mme(a,b) memset((a),(b),sizeof((a)))
#define test printf("**-**\n")
#define fuck(x) cout<<"* "<<x<<"\n"
#define iis std::ios::sync_with_stdio(false)
using namespace std;
typedef long long LL;
const int MXN = 1e3 + 7;
const int MXE = 1e6 + 7;
const int mod = 998244353;
const int INF = 0x3f3f3f3f;
const LL INFLL = 0x3f3f3f3f3f3f3f3f;
typedef pair<int,int> pii;
int n, m, t;
int ar[MXN], br[MXN], cr[MXN], dr[MXN];
int nx[MXN], ny[MXN], tx, ty;
int vis[MXN][MXN], dir[4][2] = {1,0,0,1,-1,0,0,-1}, tot;
LL ans[MXN];
void dfs(int x,int y){
vis[x][y] = tot;
for(int i = 0; i < 4; ++i){
int px = x + dir[i][0], py = y + dir[i][1];
if(vis[px][py]||px < 0||py < 0||px >= tx||py >= ty)continue;
vis[px][py] = tot;
dfs(px, py);
}
}
int main(){
int tim, tc = 0;
scanf("%d", &tim);
while(tim--){
scanf("%d%d%d", &n, &m, &t);
int p = 0, k = 0;
for(int i = 0; i < t; ++i){
scanf("%d%d", &ar[i], &br[i]);
cr[p++] = ar[i];
}
cr[p++] = 1;cr[p++] = n;
sort(cr, cr + p);
p = unique(cr, cr + p)-cr;
k = p;
for(int i = 1; i < p; ++i){
cr[k++] = cr[i-1]+1;
cr[k++] = cr[i]-1;
}
sort(cr, cr + k);
k = unique(cr, cr + k)-cr;
tx = k;
for(int i = 0; i < t; ++i){
nx[i] = lower_bound(cr, cr + k, ar[i]) - cr;
}
p = 0;
for(int i = 0; i < t; ++i){
dr[p++] = br[i];
}
dr[p++] = 1;dr[p++] = m;
sort(dr, dr + p);
p = unique(dr, dr + p)-dr;
k = p;
for(int i = 1; i < p; ++i){
dr[k++] = dr[i-1]+1;
dr[k++] = dr[i]-1;
}
sort(dr, dr + k);
k = unique(dr, dr + k)-dr;
ty = k;
for(int i = 0; i < t; ++i){
ny[i] = lower_bound(dr, dr + k, br[i]) - dr;
}
//以上离散化
mme(vis, 0); tot = 0;
for(int i = 0; i < t; ++i){
//printf("%d %d\n", cr[nx[i]], dr[ny[i]]);
vis[nx[i]][ny[i]] = -1;
}
for(int i = 0; i < tx; ++i){
for(int j = 0; j < ty; ++j){
if(vis[i][j] == 0){
tot++;
dfs(i, j);
}
}
}
printf("Case #%d:\n%d\n", ++tc, tot);
mme(ans, 0);
for(int i = 0; i < tx; ++i){
for(int j = 0; j < ty; ++j){
//printf("%d ", vis[i][j]);
if(vis[i][j] <= 0)continue;
LL a = cr[i], b = dr[j];
if(i) a -= cr[i-1];
if(j) b -= dr[j-1];
ans[vis[i][j]] += a*b;
//printf("%d %d %lld\n",i,j,a*b);
}
//printf("\n");
}
//test;
sort(ans+1, ans +1+tot);
for(int i = 1; i < tot; ++i){
printf("%lld ", ans[i]);
}
printf("%lld\n", ans[tot]);
}
return 0;
}