제출 #1219032

#제출 시각아이디문제언어결과실행 시간메모리
1219032thunoproFancy Fence (CEOI20_fancyfence)C++20
100 / 100
24 ms5192 KiB
#include <bits/stdc++.h>
using namespace std;

/* ——— HẰNG & HÀM TIỆN ÍCH ——— */
const long long MOD  = 1'000'000'007LL;
const long long INV2 = 500'000'004LL;          // 2^{-1} mod MOD
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){
    return mulmod(mulmod(L%MOD, (L+1)%MOD), INV2);
}
inline long long sumRange(long long lo,long long hi){          // lo..hi, lo≤hi
    if(lo>hi) return 0;
    long long cnt = (hi - lo + 1) % MOD;
    long long s   = (lo + hi) % MOD;
    return mulmod(mulmod(cnt, s), INV2);
}

/* ——— DSU ——— */
struct DSU{
    vector<int> par;              // <0: size
    vector<long long> len;        // độ rộng run
    DSU(int n): par(n,-1), len(n,0) {}
    int find(int x){ return par[x]<0?x:par[x]=find(par[x]); }
};

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.begin(), ord.end(), [&](auto &a,auto &b){
        return a.first > b.first;          // height giảm
    });

    DSU dsu(N);
    vector<char> active(N,0);
    long long F = 0;          // ∑_{run} C(runWidth+1,2) mod MOD
    long long ans = 0;

    size_t pos = 0;
    while(pos < ord.size()){
        long long H = ord[pos].first;              // chiều cao đang xử lý

        /* ——— kích hoạt mọi đoạn có height = H ——— */
        while(pos < ord.size() && ord[pos].first == H){
            int idx = ord[pos].second;
            active[idx] = 1;
            dsu.len[idx] = w[idx];
            F = addmod(F, choose2(w[idx]));        // run mới

            auto merge = [&](int a,int b){
                if(b<0 || b>=N || !active[b]) return;
                a = dsu.find(a); b = dsu.find(b);
                if(a==b) return;
                long long L1 = dsu.len[a], L2 = dsu.len[b];
                F = submod(F, choose2(L1));
                F = submod(F, choose2(L2));

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

                F = addmod(F, choose2(dsu.len[a]));
            };
            merge(idx, idx-1);
            merge(idx, idx+1);
            ++pos;
        }

        /* ——— xác định chiều cao kế tiếp ——— */
        long long nextH = (pos < ord.size() ? ord[pos].first : 0);
        /* cộng phần đóng góp của k = nextH+1 .. H */
        long long sumK = sumRange(nextH+1, H);
        ans = addmod(ans, mulmod(F, sumK));
    }

    cout << ans << '\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...