HHKB Programming Contest 2020 E-Lamps (number of proposals)

Insert picture description here

Meaning:
... Represents a lamp,
each.... Can point flashlight, illuminated four directions.. (Including yourself) until you encounter a boundary or encounter #.
For all lighting plans, find the total number of lighting.

Idea:
Just need for each .... Contribution alone.
Set.... The totalkkk ,
a.... The number of lighting scheme: If all four directions.. The number ismmm , then the number of lit schemes is(2 m − 1) ∗ (2 k − m) (2^{m}-1)*(2^{km})(2m1)(2km)

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
using namespace std;

typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn = 2e3 + 7;
const int mod = 1e9 + 7;

ll p[maxn * maxn];
char s[maxn][maxn];
int U[maxn][maxn],D[maxn][maxn],L[maxn][maxn],R[maxn][maxn];
int n,m;

void init() {
    
    
    p[0] = 1;
    for(int i = 1;i <= maxn * maxn - 2;i++) {
    
    
        p[i] = p[i - 1] * 2 % mod;
    }
    memset(U,0x3f,sizeof(U));
    for(int i = 1;i <= n;i++) {
    
    
        for(int j = 1;j <= m;j++) {
    
    
            if(s[i][j] == '.') {
    
    
                U[i][j] = i;
                U[i][j] = min(U[i][j],U[i - 1][j]);
            }
        }
    }
    
    for(int i = n;i >= 1;i--) {
    
    
        for(int j = 1;j <= m;j++) {
    
    
            if(s[i][j] == '.') {
    
    
                D[i][j] = i;
                D[i][j] = max(D[i][j],D[i + 1][j]);
            }
        }
    }
    
    memset(L,0x3f,sizeof(L));
    for(int j = 1;j <= m;j++) {
    
    
        for(int i = 1;i <= n;i++) {
    
    
            if(s[i][j] == '.') {
    
    
                L[i][j] = j;
                L[i][j] = min(L[i][j],L[i][j - 1]);
            }
        }
    }
    
    for(int j = m;j >= 1;j--) {
    
    
        for(int i = 1;i <= n;i++) {
    
    
            if(s[i][j] == '.') {
    
    
                R[i][j] = j;
                R[i][j] = max(R[i][j],R[i][j + 1]);
            }
        }
    }
}

int main() {
    
    
    scanf("%d%d",&n,&m);
    int cnt = 0;
    for(int i = 1;i <= n;i++) {
    
    
        scanf("%s",s[i] + 1);
        for(int j = 1;j <= m;j++) {
    
    
            if(s[i][j] == '.') {
    
    
                cnt++;
            }
        }
    }
    init();
    ll ans = 0;
    for(int i = 1;i <= n;i++) {
    
    
        for(int j = 1;j <= m;j++) {
    
    
            if(s[i][j] == '.') {
    
    
                int num = D[i][j] - U[i][j] + R[i][j] - L[i][j] + 1;
                ans = (ans + p[cnt - num] * (p[num] - 1) % mod + mod) % mod;
            }
        }
    }
    printf("%lld\n",((ans + mod) % mod));
    return 0;
}

Guess you like

Origin blog.csdn.net/tomjobs/article/details/109017052