Submission #1324660

#TimeUsernameProblemLanguageResultExecution timeMemory
1324660lesinhhungFlooding Wall (BOI24_wall)C++20
100 / 100
594 ms40360 KiB
//    _____               __________      ______    ______
//   |    |              /    ___   \    |     |   |     |
//   |    |             /    /  |___|    |     |   |     |
//   |    |            |    \_____       |     |___|     |
//   |    |            \______    \      |      ____     |
//   |    |______     _____  \    |      |     |   |     |
//   |          |    |    |_/    /       |     |   |     |
//   |__________|    \__________/        |_____|   |_____|
//
//   Code boi Le Sinh Hung dep trai

#include <bits/stdc++.h>

using namespace std;

static const uint32_t MOD = 1000000007u;

static inline uint32_t addmod(uint32_t a, uint32_t b) {
    uint32_t s = a + b;
    if (s >= MOD) s -= MOD;
    return s;
}
static inline uint32_t submod(uint32_t a, uint32_t b) {
    return (a >= b) ? (a - b) : (a + MOD - b);
}
static inline uint32_t mulmod(uint32_t a, uint32_t b) {
    return (uint32_t)((uint64_t)a * b % MOD);
}

struct SegTree {
    int n, orig_n;
    vector<uint32_t> prod, sum;
    const uint32_t* w; 

    SegTree() : n(0), orig_n(0), w(nullptr) {}

    void init(int N, const uint32_t* weights) {
        orig_n = N;
        w = weights;
        n = 1;
        while (n < N) n <<= 1;
        prod.assign(2 * n, 1u);
        sum.assign(2 * n, 0u);

        for (int i = 0; i < n; ++i) {
            int v = n + i;
            if (i < orig_n) {
                prod[v] = 0u;
                sum[v] = 0u;
            } else {
                prod[v] = 1u;
                sum[v] = 0u;
            }
        }
        for (int v = n - 1; v >= 1; --v) pull(v);
    }

    inline void pull(int v) {
        uint32_t pl = prod[v << 1];
        uint32_t pr = prod[v << 1 | 1];
        prod[v] = mulmod(pl, pr);
        sum[v] = addmod(sum[v << 1], mulmod(pl, sum[v << 1 | 1]));
    }

    inline void set_val(int pos1, uint32_t c) {
        int pos = pos1 - 1;
        int v = n + pos;
        prod[v] = c;
        sum[v] = mulmod(w[pos], c);
        for (v >>= 1; v; v >>= 1) pull(v);
    }

    inline uint32_t all_prod() const { return prod[1]; }
    inline uint32_t weighted_prefix_sum() const { return sum[1]; }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N;
    cin >> N;

    vector<int> a(N + 1), b(N + 1);
    vector<int> vals;
    vals.reserve(2 * (size_t)N);

    for (int i = 1; i <= N; i++) { cin >> a[i]; vals.push_back(a[i]); }
    for (int i = 1; i <= N; i++) { cin >> b[i]; vals.push_back(b[i]); }

    sort(vals.begin(), vals.end());
    vals.erase(unique(vals.begin(), vals.end()), vals.end());
    int M = (int)vals.size();

    vector<uint32_t> pow2(N + 1);
    pow2[0] = 1;
    for (int i = 1; i <= N; i++) pow2[i] = addmod(pow2[i - 1], pow2[i - 1]);

    vector<uint32_t> w(N);
    for (int i = 1; i <= N; i++) w[i - 1] = pow2[N - i];

    SegTree segF, segR;
    segF.init(N, w.data());
    segR.init(N, w.data());

    vector<int> head1(M, -1), head2(M, -1);
    vector<int> nxt1(N + 1, -1), nxt2(N + 1, -1);

    for (int i = 1; i <= N; i++) {
        int lo = min(a[i], b[i]);
        int hi = max(a[i], b[i]);

        int k1 = (int)(upper_bound(vals.begin(), vals.end(), lo) - vals.begin());
        int k2 = (int)(upper_bound(vals.begin(), vals.end(), hi) - vals.begin());

        if (k1 < M) { nxt1[i] = head1[k1]; head1[k1] = i; }
        if (k2 < M) { nxt2[i] = head2[k2]; head2[k2] = i; }
    }

    uint32_t total_levels = 0;
    int prev = 0;

    uint32_t twoN = pow2[N];

    for (int k = 0; k < M; k++) {
        for (int idx = head1[k]; idx != -1; idx = nxt1[idx]) {
            segF.set_val(idx, 1u);
            segR.set_val(N - idx + 1, 1u);
        }
        for (int idx = head2[k]; idx != -1; idx = nxt2[idx]) {
            segF.set_val(idx, 2u);
            segR.set_val(N - idx + 1, 2u);
        }

        uint32_t A = segF.weighted_prefix_sum();
        uint32_t B = segR.weighted_prefix_sum();
        uint32_t Pall = segF.all_prod();

        uint32_t nMod = (uint32_t)(N % (int)MOD);

        uint32_t S = mulmod(nMod, twoN);
        S = submod(S, A);
        S = submod(S, B);
        S = addmod(S, mulmod(nMod, Pall));

        int deltaInt = vals[k] - prev;
        uint32_t delta = (uint32_t)(deltaInt % (int)MOD);
        total_levels = addmod(total_levels, mulmod(delta, S));

        prev = vals[k];
    }

    uint32_t sum_heights = 0;
    uint32_t coef = pow2[N - 1];
    for (int i = 1; i <= N; i++) {
        uint32_t s = (uint32_t)(((int64_t)a[i] + b[i]) % MOD);
        sum_heights = addmod(sum_heights, mulmod(s, coef));
    }

    uint32_t ans = submod(total_levels, sum_heights);
    cout << ans;
    
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...