?

11  •  1个月前


#include <bits/stdc++.h>
#define int long long

// 读入整数,支持负数
inline int read() {
    int x = 0;
    bool f = true;
    char ch = getchar();
    // 跳过非数字字符,如果遇到'-',标记负数
    for (; !isdigit(ch); ch = getchar())
        if (ch == '-')
            f = false;
    // 将字符转换为整数
    for (; isdigit(ch); ch = getchar())
        x = (x << 1) + (x << 3) + ch - '0';
    return f ? x : (~(x - 1));  // 返回结果,负数时取反
}

// 返回两个整数中的最大值
inline int max(int a, int b) {
    return a > b ? a : b;
}

// 更新a为a和b中的较大者,返回是否更新
inline bool gmx(int &a, int b) {
    return b > a ? a = b, true : false;
}

// 返回两个整数中的最小值
inline int min(int a, int b) {
    return a < b ? a : b;
}

const int maxn = (int)1e5 + 5;  // 定义最大数组大小
const int maxm = (int)1e5 + 5;
const int mlgn = 25;
const int mlgm = 25;
int amx[maxn][mlgn], amn[maxn][mlgn], afx[maxn][mlgn], azn[maxn][mlgn];
int bmx[maxm][mlgm], bmn[maxm][mlgm];
int lg[maxn];  // 用于存储对数值
const int maxinf = LONG_LONG_MAX, mininf = LONG_LONG_MIN;

signed main() {
    // 读取 n、m、q
    int n = read(), m = read(), q = read();
    
    // 初始化 a 数组的最大值、最小值、负最大值、正最小值
    for (int i = 1; i <= n; ++i) {
        int x = read();
        amx[i][0] = amn[i][0] = x;
        afx[i][0] = (x < 0 ? x : mininf);  // 若x为负数,记录其值,否则记录最小负数
        azn[i][0] = (x >= 0 ? x : maxinf); // 若x为非负数,记录其值,否则记录最大正数
    }

    // 初始化 b 数组的最大值、最小值
    for (int i = 1; i <= m; ++i) {
        int x = read();
        bmx[i][0] = bmn[i][0] = x;
    }

    // 计算 log 值,用于区间查询
    for (int i = 2; i <= max(n, m); ++i)
        lg[i] = lg[i >> 1] + 1;

    // 预处理a数组,计算出所有区间的最大值、最小值、负最大值、正最小值
    for (int j = 1; j <= lg[n]; ++j) {
        for (int i = 1; i + (1 << j) - 1 <= n; ++i) {
            int p = i + (1 << (j - 1));
            amx[i][j] = max(amx[i][j - 1], amx[p][j - 1]);
            afx[i][j] = max(afx[i][j - 1], afx[p][j - 1]);
            amn[i][j] = min(amn[i][j - 1], amn[p][j - 1]);
            azn[i][j] = min(azn[i][j - 1], azn[p][j - 1]);
        }
    }

    // 预处理b数组,计算出所有区间的最大值、最小值
    for (int j = 1; j <= lg[m]; ++j) {
        for (int i = 1; i + (1 << j) - 1 <= m; ++i) {
            int p = i + (1 << (j - 1));
            bmx[i][j] = max(bmx[i][j - 1], bmx[p][j - 1]);
            bmn[i][j] = min(bmn[i][j - 1], bmn[p][j - 1]);
        }
    }

    // 处理每个查询
    while (q--) {
        int la = read(), ra = read(), lb = read(), rb = read();
        int sa = lg[ra - la + 1], sb = lg[rb - lb + 1];
        int pa = ra - (1 << sa) + 1, pb = rb - (1 << sb) + 1;
        
        // 查询 a、b 的区间最大值、最小值
        int amax = max(amx[la][sa], amx[pa][sa]);
        int amin = min(amn[la][sa], amn[pa][sa]);
        int afmx = max(afx[la][sa], afx[pa][sa]);
        int azmn = min(azn[la][sa], azn[pa][sa]);
        int bmax = max(bmx[lb][sb], bmx[pb][sb]);
        int bmin = min(bmn[lb][sb], bmn[pb][sb]);
        
        int ans = mininf;  // 初始化答案为最小值

        // 比较各组合的结果,得到最大值
        gmx(ans, amax * (amax >= 0 ? bmin : bmax));
        gmx(ans, amin * (amin >= 0 ? bmin : bmax));
        if (afmx != mininf) gmx(ans, afmx * (afmx >= 0 ? bmin : bmax));
        if (azmn != maxinf) gmx(ans, azmn * (azmn >= 0 ? bmin : bmax));
        
        // 输出结果
        printf("%lld\n", ans);
    }
    return 0;
}


评论:

请先登录,才能进行评论