Submission #1219031

#TimeUsernameProblemLanguageResultExecution timeMemory
1219031thunoproFancy Fence (CEOI20_fancyfence)C++20
0 / 100
1 ms328 KiB
#include <bits/stdc++.h>
using namespace std;

const long long MOD = 1'000'000'007LL;
const long long INV2 = 500'000'004LL;          // 2^(-1) mod MOD

struct DSU {
    vector<int> p;             // parent (-size for root)
    vector<long long> len;     // tổng bề rộng thật của run
    DSU(int n): p(n, -1), len(n, 0) {}
    int find(int x){ return p[x] < 0 ? x : p[x] = find(p[x]); }
};

inline long long addmod(long long a, long long b){
    a += b;
    if(a >= MOD) a -= MOD;
    return a;
}
inline long long submod(long long a, long long b){
    a -= b;
    if(a < 0) a += MOD;
    return a;
}
inline long long mulmod(long long a, long long b){
    return (a % MOD) * (b % MOD) % MOD;
}
inline long long choose2(long long L){                // (L+1 choose 2) mod MOD
    return mulmod(mulmod(L % MOD, (L + 1) % MOD), INV2);
}
// ∑_{k=lo}^{hi} k   (lo< =hi)  mod MOD
inline long long sumRange(long long lo, long long hi){
    long long sHi = mulmod(hi % MOD, (hi + 1) % MOD);
    long long sLo = mulmod(lo % MOD, (lo + 1) % MOD);
    return mulmod(submod(sHi, sLo), INV2);
}

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

    int N;
    if(!(cin >> N)) return 0;

    vector<long long> h(N), w(N);
    for(auto &x: h) cin >> x;
    for(auto &x: w) cin >> x;

    /* sắp đoạn theo chiều cao giảm dần */
    vector<pair<long long,int>> ord;
    ord.reserve(N);
    for(int i = 0; i < N; ++i) ord.push_back({h[i], i});
    sort(ord.rbegin(), ord.rend());

    DSU dsu(N);
    vector<char> active(N, 0);
    long long F = 0;               // tổng (runWidth+1 choose 2) hiện thời
    long long ans = 0;

    long long prevH = ord.empty() ? 0 : ord[0].first + 1;
    size_t pos = 0;

    while(pos < ord.size()){
        long long curH = ord[pos].first;

        /* 1. đóng góp cho mọi k trong (curH, prevH] */
        if(prevH > curH){
            long long sumK = sumRange(curH, prevH - 1);
            ans = mulmod(ans + F * sumK % MOD, 1);     // giữ mod
        }

        /* 2. kích hoạt các đoạn cao = curH */
        while(pos < ord.size() && ord[pos].first == curH){
            int idx = ord[pos].second;
            active[idx] = 1;
            dsu.len[idx] = w[idx];

            F = addmod(F, choose2(w[idx]));            // run mới

            auto tryMerge = [&](int u, int v){
                if(v < 0 || v >= N || !active[v]) return;
                u = dsu.find(u); v = dsu.find(v);
                if(u == v) return;
                long long L1 = dsu.len[u], L2 = dsu.len[v];

                F = submod(F, choose2(L1));
                F = submod(F, choose2(L2));

                /* gộp v vào u */
                dsu.p[u] += dsu.p[v];
                dsu.p[v] = u;
                dsu.len[u] = L1 + L2;

                F = addmod(F, choose2(dsu.len[u]));
            };
            tryMerge(idx, idx - 1);
            tryMerge(idx, idx + 1);

            ++pos;
        }
        prevH = curH;
    }

    /* 3. dải còn lại k = 1 .. prevH */
    if(prevH){
        long long sumK = sumRange(0, prevH - 1);       // 0..prevH-1  ⇒ 1..prevH
        ans = (ans + F * sumK) % MOD;
    }

    cout << ans % MOD << '\n';
    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...
#Verdict Execution timeMemoryGrader output
Fetching results...