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;
}

posted @ 2026-03-19 17:10  Hootime  阅读(1)  评论(0)    收藏  举报