求助,线段树喜提暴力分
查看原帖
求助,线段树喜提暴力分
284123
__Remake__楼主2022/11/4 01:18

RT,大致思路是维护区间最大值 (mx) 、最小值 (mn) 、最大非正数 (nmx) 、最小非负数 (nmn) 、是否全非正 (eg) 、是否全非负 (neg) 。

MnZn打线段树的次数不多,不知道哪里写挂了qwq

#include <iostream>
#include <cstdlib>

#define MAXN 100007
#define INF 0x3f3f3f3f
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define RE register

using namespace std;

typedef long long ll;

int n, m, q, lt1, rt1, lt2, rt2;

ll a[MAXN], b[MAXN];

struct node {
    int l, r; ll mx, mn, nmx, nmn; bool eg, neg;
    node() {l = 0, r = 0, mx = -INF, mn = INF, nmx = -INF, nmn = INF, eg = false, neg = false; }
}sA[MAXN << 2], sB[MAXN << 2];

inline void update(node* T, int d) {
    T[d].mx = max(T[(d << 1)].mx, T[((d << 1) | 1)].mx); T[d].mn = min(T[(d << 1)].mn, T[((d << 1) | 1)].mn);
    T[d].nmx = max(T[(d << 1)].nmx, T[((d << 1) | 1)].nmx); T[d].nmn = min(T[(d << 1)].nmn, T[((d << 1) | 1)].nmn);
    T[d].eg = T[(d << 1)].eg && T[((d << 1) | 1)].eg; T[d].neg = T[(d << 1)].neg && T[((d << 1) | 1)].neg;
    return ;
}

inline void build(ll* ar, node* T, int lp, int rp, int d) {
    T[d].l = lp, T[d].r = rp;
    if(lp == rp) {
        T[d].mx = T[d].mn = ar[lp];
        if(ar[lp] <= 0) { T[d].nmx = ar[lp]; T[d].eg = true; }
        if(ar[lp] >= 0) { T[d].nmn = ar[lp]; T[d].neg = true; }
        return ;
    }
    int mid = (lp + rp) >> 1;
    build(ar, T, lp, mid, (d << 1));
    build(ar, T, mid + 1, rp, (d << 1) | 1);
    update(T, d);
    return ;
}

inline ll akm(node* T, int lp, int rp, int d) {
    if(lp <= T[d].l && T[d].r <= rp) return T[d].mx;
    int mid = (T[d].l + T[d].r) >> 1;
    int fs = -INF;
    if(lp <= mid) fs = max(fs, akm(T, lp, rp, (d << 1)));
    if(rp > mid) fs = max(fs, akm(T, lp, rp, ((d << 1) | 1)));
    return fs;
}

inline ll akn(node* T, int lp, int rp, int d) {
    if(lp <= T[d].l && T[d].r <= rp) return T[d].mn;
    int mid = (T[d].l + T[d].r) >> 1;
    int fs = INF;
    if(lp <= mid) fs = min(fs, akn(T, lp, rp, (d << 1)));
    if(rp > mid) fs = min(fs, akn(T, lp, rp, ((d << 1) | 1)));
    return fs;
}

inline ll aknm(node* T, int lp, int rp, int d) {
    if(lp <= T[d].l && T[d].r <= rp) return T[d].nmx;
    int mid = (T[d].l + T[d].r) >> 1;
    int fs = -INF;
    if(lp <= mid) fs = max(fs, aknm(T, lp, rp, (d << 1)));
    if(rp > mid) fs = max(fs, aknm(T, lp, rp, ((d << 1) | 1)));
    return fs;
}

inline ll aknn(node* T, int lp, int rp, int d) {
    if(lp <= T[d].l && T[d].r <= rp) return T[d].nmn;
    int mid = (T[d].l + T[d].r) >> 1;
    int fs = INF;
    if(lp <= mid) fs = min(fs, aknn(T, lp, rp, (d << 1)));
    if(rp > mid) fs = min(fs, aknn(T, lp, rp, ((d << 1) | 1)));
    return fs;
}

inline bool aeg(node* T, int lp, int rp, int d) {
    if(lp > rp) return false;
    if(lp <= T[d].l && T[d].r <= rp) return T[d].eg;
    int mid = (T[d].l + T[d].r) >> 1;
    bool fs = true;
    if(lp <= mid) fs = fs && aeg(T, lp, rp, (d << 1));
    if(!fs) return false;
    if(rp > mid) fs = fs && aeg(T, lp, rp, ((d << 1) | 1));
    return fs;
}

inline bool aneg(node* T, int lp, int rp, int d) {
    if(lp > rp) return false;
    if(lp <= T[d].l && T[d].r <= rp) return T[d].neg;
    int mid = (T[d].l + T[d].r) >> 1;
    bool fs = true;
    if(lp <= mid) fs = fs && aneg(T, lp, rp, (d << 1));
    if(!fs) return false;
    if(rp > mid) fs = fs && aneg(T, lp, rp, ((d << 1) | 1));
    return fs;
}

int main() {
    freopen("game3.in", "r", stdin);
    freopen("game3.out", "w", stdout);
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cin >> n >> m >> q;
    for(RE int i = 1; i <= n; i++) cin >> a[i];
    for(RE int i = 1; i <= m; i++) cin >> b[i];
    build(a, sA, 1, n, 1); build(b, sB, 1, m, 1);
    for(RE int i = 1; i <= q; i++) {
        cin >> lt1 >> rt1 >> lt2 >> rt2;
        if(aeg(sA, lt1, rt1, 1)) {
            ll tm = akm(sB, lt2, rt2, 1);
            if(aeg(sB, lt2, rt2, 1)) cout << 1LL * tm * akn(sA, lt1, rt1, 1) << endl;
            else cout << 1LL * tm * akm(sA, lt1, rt1, 1) << endl;
        }
        else if(aneg(sA, lt1, rt1, 1)) {
            ll tm = akn(sB, lt2, rt2, 1);
            if(aneg(sB, lt2, rt2, 1)) cout << 1LL * tm * akm(sA, lt1, rt1, 1) << endl;
            else cout << 1LL * tm * akn(sA, lt1, rt1, 1) << endl;
        }
        else {
            if(aneg(sB, lt2, rt2, 1)) cout << 1LL * akm(sA, lt1, rt1, 1) * akn(sB, lt2, rt2, 1) << endl;
            else if(aeg(sB, lt2, rt2, 1)) cout << 1LL * akn(sA, lt1, rt1, 1) * akm(sB, lt2, rt2, 1) << endl;
            else {
                ll an_0 = 1LL * akn(sB, lt2, rt2, 1) * aknn(sA, lt1, rt1, 1), an_1 = 1LL * akm(sB, lt2, rt2, 1) * aknm(sA, lt1, rt1, 1);
                cout << max(an_0, an_1) << endl;
            }
        }
    }
    return 0;
}
2022/11/4 01:18
加载中...