Vanya and Balloons

枚举中心去更新答案, 数字过大用log去比较, 斜着的旋转一下坐标, 然后我旋出来好多bug。。。。

#include<bits/stdc++.h>
#define LL long long
#define LD long double
#define ull unsigned long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ALL(x) (x).begin(), (x).end()
#define fio ios::sync_with_stdio(false); cin.tie(0);

using namespace std;

const int N = 3000 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;
const double PI = acos(-1);

template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;}
template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;}
template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;}
template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;}

int power(int a, int b) {
    int ans = 1;
    while(b) {
        if(b & 1) ans = 1LL * ans * a % mod;
        a = 1LL * a * a % mod; b >>= 1;
    }
    return ans;
}

int n, a[N][N], b[N][N];
short row[N][N][2], col[N][N][2];
short L[N][N], R[N][N], U[N][N], D[N][N];
bool vis[N][N];

LD lg2 = logl(2), lg3 = logl(3);

bool cmp(const PII& a, const PII& b) {
    return a.fi * lg2 + a.se * lg3 < b.fi * lg2 + b.se * lg3;
}

inline int calcRow(int i, int l, int r, int op) {
    return row[i][r][op] - row[i][l][op];
}
inline int calcCol(int j, int l, int r, int op) {
    return col[j][r][op] - col[j][l][op];
}

PII calc(int a[N][N], int n) {
    PII ans = mk(0, 0);
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            if(!a[i][j]) L[i][j] = j, U[i][j] = i;
            else L[i][j] = L[i][j - 1], U[i][j] = U[i - 1][j];
            row[i][j][0] = row[i][j - 1][0] + (a[i][j] == 2);
            row[i][j][1] = row[i][j - 1][1] + (a[i][j] == 3);
            col[j][i][0] = col[j][i - 1][0] + (a[i][j] == 2);
            col[j][i][1] = col[j][i - 1][1] + (a[i][j] == 3);
        }
    }
    for(int i = n; i >= 1; i--) {
        for(int j = n; j >= 1; j--) {
            if(!a[i][j]) R[i][j] = j, D[i][j] = i;
            else {
                if(j == n) R[i][j] = j + 1;
                else R[i][j] = R[i][j + 1];
                if(i == n) D[i][j] = i + 1;
                else D[i][j] = D[i + 1][j];
            }
        }
    }
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            if(!a[i][j] || !vis[i][j]) continue;
            int d = min({i - U[i][j], D[i][j] - i, j - L[i][j], R[i][j] - j});
            PII tmp = mk(0, 0);
            tmp.fi += calcRow(i, j - d, j + d - 1, 0);
            tmp.fi += calcCol(j, i - d, i + d - 1, 0);
            tmp.se += calcRow(i, j - d, j + d - 1, 1);
            tmp.se += calcCol(j, i - d, i + d - 1, 1);
            if(a[i][j] == 2) tmp.fi--;
            else if(a[i][j] == 3) tmp.se--;
            if(cmp(ans, tmp)) {
                ans = tmp;
            }
        }
    }
    return ans;
}

int main() {
    int mask = 0;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            scanf("%1d", &a[i][j]), vis[i][j] = true, mask |= a[i][j];
    if(!mask) return puts("0"), 0;
    PII ret1 = calc(a, n);
    for(int i = 1; i <= 3 * n; i++)
        for(int j = 1; j <= 3 * n; j++)
            b[i][j] = 1, vis[i][j] = false;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            b[i - j + n][i + j + n] = a[i][j], vis[i - j + n][i + j + n] = true;
    int lx = 1 - 1 + n, ly = 1 + 1 + n;
    int rx = n - n + n, ry = n + n + n;
    int x = (lx + rx) / 2, y = (ly + ry) / 2;
    int d = abs(x - lx) + abs(y - ry);
    for(int i = 1; i <= 3 * n; i++)
        for(int j = 1; j <= 3 * n; j++)
            if(abs(i - x) + abs(j - y) > d)
                b[i][j] = 0;
    PII ret2 = calc(b, 3 * n);
    if(cmp(ret1, ret2)) {
        printf("%d\n", 1LL * power(2, ret2.fi) * power(3, ret2.se) % mod);
    } else {
        printf("%d\n", 1LL * power(2, ret1.fi) * power(3, ret1.se) % mod);
    }
    return 0;
}

/*
*/