Solution - P6008 [USACO20JAN] Cave Paintings P
主观难度:【1+】
好的。我是【数据删除】。
并查集题。
合并两个集合时把方案相乘即可,注意最后因为有全填这一方案所以总数加 \(1\)。
#include <bits/stdc++.h>
#define llong long long
#define N 1003
using namespace std;
constexpr llong p = 1e9+7;
int n, m;
char a[N][N];
llong res[N*N];
int fa[N*N];
llong ans = 1;
#define pos(x,y) ((x-1)*m+y)
#define posx(x) ((x-1)/m+1)
#define posy(x) ((x-1)%m+1)
inline int find(int x){
if(x == fa[x]) return x;
return fa[x] = find(fa[x]);
}
inline void merge(int x, int y){
x = find(x), y = find(y);
if(x != y) fa[y] = x, res[x] = res[x]*res[y]%p;
return;
}
int main(){
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; ++i) scanf("%s", a[i]+1);
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
fa[pos(i,j)] = pos(i, j), res[pos(i,j)] = 1;
for(int i = n-1; i > 1; --i){
for(int j = 2; j < m; ++j){
if(a[i][j] == '#') continue;
merge(pos(i, j), pos(i, j-1));
merge(pos(i, j), pos(i+1, j));
}
for(int j = 2; j < m; ++j){
if(a[i][j] == '#'){
fa[pos(i, j)] = pos(i, j);
continue;
}
if(pos(i, j) == find(pos(i, j)))
res[pos(i,j)] = (res[pos(i,j)]+1)%p;
}
}
for(int i = 2; i < n; ++i){
for(int j = 2; j < m; ++j){
if(a[i][j] == '#') continue;
if(pos(i, j) == find(pos(i, j)))
ans = (ans*res[pos(i,j)])%p;
}
}
printf("%lld", ans);
return 0;
}

浙公网安备 33010602011771号