Gluttonous Goop

As a prominent researcher in the laboratorium for Breathtaking Agriculture through Petri dish Cultivation, you keep on looking for new organisms that might be the food of the future. Recently you have discovered a new fungus-type organism that seems to be nutritious and very efficient in converting energy from food to body mass. You have placed a small batch surrounded by food in a petri dish and watched it grow for a bit.

However, now that the weekend has arrived, you would rather spend some time with your loved ones than stare at the contents of this petri dish all the time (even though it is a fun guy). You cannot leave without taking the necessary precautions. What if the fungus grows too large and starts eating away at the rest of the laboratory?!

You model the situation as follows: you divide the plane into 1 × 1-squares, and draw where the fungus currently is. You know that every time step, if the fungus occupies a square, it will expand to all eight neighbouring squares (and still occupy the initial square). You know how many time steps you will be gone for over the weekend, and now you want to know how many squares the fungus will occupy when you get back.

dc27b42ba4.png

Figure G.1: Example of fungus growth: the fungus from sample 2 after 0, 1, 2 time steps. The middle image corresponds to the correct output for sample 2.

N.B.: In the input, the fungus will be given on a finite grid, but it can (and will!) grow beyond these boundaries. The fungus is not so easily contained.

input

First a line containing integers 1 \le r, c \le 201≤r,c≤20 , and 0 \le k \le 10^60≤k≤10
6
, denoting the number of rows and columns of the initial grid and the number of time steps.

Then follow r lines of c characters, each character being either ‘.’ or ‘#’. A ‘#’ denotes that the fungus is occupying this square. The fungus need not be connected.

output

Output the number of squares the fungus occupies after k time steps have passed.

样例输入1
5 5 3
.....
.###.
.#.#.
.###.
.....
样例输出1
81
样例输入2
3 3 1
#..
.#.
..#
样例输出2
19
样例输入3
1 1 1000000
#
样例输出3
4000004000001

扫描线板子题

#include <bits/stdc++.h>

#define ll long long
using namespace std;
const int M = 30;
int n, m, u, tot;
char a[M][M];
unordered_map<int, int> val;

struct P {
    int x, y1, y2;
    int k;

    inline bool operator<(const P &a) const {
        return x < a.x;
    }
} dat[M * M * 2];

int row[M * M * 2];
struct T {
    int l, r, cnt;
    int len;
#define l(x) t[x].l
#define r(x) t[x].r
#define c(x) t[x].cnt
#define len(x) t[x].len
} t[M * M * 8];

void build(int p, int l, int r) {
    l(p) = l, r(p) = r, c(p) = len(p) = 0;
    if (l == r)return;
    int mid = (l + r) >> 1;
    build(p << 1, l, mid);
    build(p << 1 | 1, mid + 1, r);
}

void change(int p, int l, int r, int k) {
    if (l <= l(p) && r >= r(p)) {
        c(p) += k;
        if (c(p))len(p) = row[r(p) + 1] - row[l(p)];
        else
            len(p) = l(p) != r(p) ? len(p << 1) + len(p << 1 | 1) : 0;
        return;
    }
    int mid = (l(p) + r(p)) >> 1;
    if (l <= mid)change(p << 1, l, r, k);
    if (r > mid)change(p << 1 | 1, l, r, k);
    if (!c(p))len(p) = len(p << 1) + len(p << 1 | 1);
}

int main() {
    scanf("%d%d%d", &n, &m, &u);
    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++)
            if (a[i][j] == '#') {
                tot += 2;
                dat[tot - 1].x = i, dat[tot].x = i + u * 2 + 1;
                row[tot - 1] = dat[tot].y1 = dat[tot - 1].y1 = j;
                row[tot] = dat[tot].y2 = dat[tot - 1].y2 = j + u * 2 + 1;
                dat[tot - 1].k = 1, dat[tot].k = -1;
            }
    if (!tot) {
        puts("0");
        return 0;
    }
    sort(row + 1, row + tot + 1);
    int tc = unique(row + 1, row + tot + 1) - (row + 1);
    for (int i = 1; i <= tc; i++)val[row[i]] = i;
    sort(dat + 1, dat + 1 + tot);
    build(1, 1, tc - 1);
    ll ans = 0;
    for (int i = 1; i <= tot - 1; i++) {
        int l = val[dat[i].y1], r = val[dat[i].y2] - 1;
        change(1, l, r, dat[i].k);
        ans += 1ll * (dat[i + 1].x - dat[i].x) * len(1);
    }
    printf("%lld\n", ans);
    return 0;
}
发布了331 篇原创文章 · 获赞 28 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_45323960/article/details/105011090