[2020.11.14提高组模拟] 鬼渊传说(village)

GMOJ​ 6862.鬼渊传说

一道由不会证的结论 + 十分繁琐 (code) 组成的题,改了一个晚上 + 半个早上......

差评!

(Solution)

首先由 欧拉公式 (%%%LZA):( ext{n + r - m = 2}),其中 (n) 为点数,(r) 为面数(包括整个图之外的面), (m) 为边数。

若不存在空腔,则 (r =) 四元环个数 (+ 1),(将四元环看成一个面),综上得:(n +) 四元环个数 (- m = 1)

那么不考虑空腔的话,可以枚举 (O(n^3)) 上下右边界,将 (n)(m)、四元环个数分别前缀和预处理好,用一个桶 (O(1)) 查询合法左边界个数即可。前缀和时需注意横竖边,为避免繁琐细节可以分为横、竖边分别前缀和,但是依旧很繁琐好吗

若一个矩形包含空腔,那么其向任意方向扩展后也依旧包含空腔,注意空腔个数上限 (n^2),所以可以预处理出所有空腔,对于空腔所在的最小的子矩形 ((x1, y1, x2, y2)),若上界 (i < x1),那么在 ((x2 + 1, y2 + 1)) 打上 (y1 - 1) 的限制,同样 (O(n^2)),最后记得下传(((x, y) ightarrow (x + 1, y))),指针 + 桶维护即可。

时间复杂度 (O(n ^ 3))

(Code)

丑的心态很爆炸

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

#define N 301
#define M 90001
#define inf 1000000

#define fo(i, x, y) for(int i = x; i <= y; i ++)

struct Arr {
    int x, y;

    bool operator == (const Arr& a) {
        return x == a.x && y == a.y;
    }
};

struct Mat {
    int x1, y1, x2, y2, fx, fy;

    void Insert(int x, int y) { x1 = x2 = fx = x, y1 = y2 = fy = y; }

    Arr operator = (const Arr& a) {
        return (Arr) { fx = a.x, fy = a.y };
    }

    void operator += (const Mat &a) {
        x1 = min(x1, a.x1), y1 = min(y1, a.y1);
        x2 = max(x2, a.x2), y2 = max(y2, a.y2);
    }
} p[N + 1][N + 1];

struct Mat1 {
    int x1, y1, x2, y2;
    void operator = (const Mat& a) {
        x1 = a.x1, y1 = a.y1, x2 = a.x2, y2 = a.y2;
    }
} c[M + 1];

char ch[N + 1][N + 1];

int fn[N + 1][N + 1], fm[N + 1][N + 1], fr[N + 1][N + 1], a[N + 1][N + 1], gm[N + 1][N + 1];

int n, m, tot = 0;

Arr Getf(int x, int y) { return (x == p[x][y].fx && y == p[x][y].fy) ? (Arr) { x, y } : p[x][y] = Getf(p[x][y].fx, p[x][y].fy); }

void Merge(int x1, int y1, int x2, int y2) {
    Arr u = Getf(x1, y1), v = Getf(x2, y2);
    if (u == v) return;
    p[u.x][u.y] += p[v.x][v.y];
    p[v.x][v.y].fx = u.x, p[v.x][v.y].fy = u.y;
}

void Init() {
    fo(i, 1, n) fo(j, 1, m) a[i][j] = ch[i][j] - 48;
    fo(i, 1, n) fo(j, 1, m)
        fn[i][j] = fn[i - 1][j] + fn[i][j - 1] - fn[i - 1][j - 1] + a[i][j];
    fo(i, 1, n) fo(j, 1, m)
        fm[i][j] = fm[i - 1][j] + fm[i][j - 1] - fm[i - 1][j - 1] + (a[i][j] & a[i][j - 1]);
    fo(i, 1, n) fo(j, 1, m)
        fr[i][j] = fr[i - 1][j] + fr[i][j - 1] - fr[i - 1][j - 1] + (a[i][j] & a[i - 1][j] & a[i][j - 1] & a[i - 1][j - 1]);
    fo(i, 1, n) fo(j, 1, m)
        gm[i][j] = gm[i - 1][j] + gm[i][j - 1] - gm[i - 1][j - 1] + (a[i][j] & a[i - 1][j]);
    fo(i, 1, n) fo(j, 1, m) if (! a[i][j]) {
        p[i][j].Insert(i, j);
        if (j > 1 && ! a[i][j - 1])
            Merge(i, j - 1, i, j);
        if (i > 1 && ! a[i - 1][j])
            Merge(i - 1, j, i, j);
    }
    fo(i, 1, n) fo(j, 1, m)
        if ((Arr) { i, j } == Getf(i, j))
        	c[ ++ tot ] = p[i][j];
}

int s[N + 1][N + 1], h[inf << 5];

#define f1(j, k) (fn[j][k] + fr[j][k + 1] - fm[j][k + 1] - gm[j][k])
#define f2(i, k) (fn[i][k] + fr[i + 1][k] - gm[i + 1][k] - fm[i][k])
#define f3(i, j) (fn[i - 1][j - 1] + fr[i][j] - (fm[i - 1][j] + gm[i][j - 1]))
#define f(i, j) (fn[i][j] + fr[i][j] - fm[i][j] - gm[i][j])

int main() {
    freopen("village.in", "r", stdin);
    freopen("village.out", "w", stdout);

    scanf("%d %d
", &n, &m);
    fo(i, 1, n) scanf("%s
", ch[i] + 1);

    Init();

    int ans = 0;
    fo(i, 1, n) {
        fo(j, 0, n) fo(k, 0, m) s[j][k] = -1;
        fo(j, 1, tot) if (i < c[j].x1)
            s[c[j].x2 + 1][c[j].y2 + 1] = max(c[j].y1 - 1, s[c[j].x2 + 1][c[j].y2 + 1]);
        fo(k, 1, m) fo(j, 1, n) s[j][k] = max(s[j][k], s[j - 1][k]);
        fo(j, i, n) {
            int l = 0;
            fo(k, 0, m) {
                if (k) {
                    while (l < s[j][k] && l <= k)
                        -- h[f3(i, l + 1) - f1(j, l) + inf], ++ l;
                    ans += h[1 - (f(j, k) - f2(i - 1, k)) + inf];
                }
                ++ h[f3(i, k + 1) - f1(j, k) + inf];
            }
            while (l <= m)
                -- h[f3(i, l + 1) - f1(j, l) + inf], ++ l;
        }
    }
    printf("%d
", ans);

    return 0;
}

原文地址:https://www.cnblogs.com/zhouzj2004/p/13975752.html