Submission #1329652

#TimeUsernameProblemLanguageResultExecution timeMemory
1329652yudyudFancy Fence (CEOI20_fancyfence)C++20
25 / 100
33 ms10680 KiB
#include <bits/stdc++.h>
using namespace std;

#define float double
#define int long long
#define ii pair<int , int>
#define iii pair<int , ii>
#define fs first
#define sd second
#define all(a) a.begin(),a.end()
#define FOR(I , L , R) for(int I (L) ; I <= (int)R ; I++)
#define FOD(I , L , R) for(int I (L) ; I >= (int)R ; I--)
#define FOA(I , A) for(auto I : A)
#define printr(A , L , R) FOR(I , L , R){cout << A[I] << ' ';}
#define printd(A , L , R) FOD(I , L , R){cout << A[I] << ' ';}
#define printa(A) FOA(I , A){cout << I << ' ';}
#define quick ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

const int N = 1e5 + 5 , mod = 1e9 + 7;

int n;
int h[N] , w[N];

int ltn(int ra , int rb){
    int res = 1;
    while(rb > 0){
        if (rb % 2 == 1){
            res = res * ra % mod;
        }
        ra = ra * ra % mod;
        rb >>= 1;
    }
    return res;
}

namespace sub2{

    void solve(){
        int tong = 0;
        FOR(i , 1 , n){
            tong += w[i];
        }
        cout << ((tong % mod) * ((tong + 1) % mod)) % mod * ltn(2 , mod - 2) % mod * (((h[1] * (h[1] + 1) % mod) % mod) * ltn(2 , mod - 2)) % mod;
    }
}

namespace sub3{
    int MOD2 = ltn(2 , mod - 2);
    int G(int u , int v){
        return ((u % mod * ((u + 1) % mod)) % mod * MOD2 % mod) * ((v % mod * ((v + 1) % mod)) % mod * MOD2 % mod) % mod;
    }
    void solve(){
        int tong = 0 , ans = 0;
        FOR(i , 1 , n){
            tong += w[i];
        }
        FOR(i , 1 , n){
            ans = (ans + G(h[i] , tong)) % mod;
            if (i > 1){
                ans = (ans - G(h[i - 1] , tong) + mod) % mod;
            }
            tong -= w[i];
        }
        cout << ans;
    }
}

struct seg{
    int sg[N << 2];

    void update(int id , int l , int r , int pos , int val){
        if (l > pos || r < pos){
            return;
        }

        if (l == r){
            sg[id] = val;
            return;
        }

        int mid = (l + r) >> 1;
        update(id << 1 , l , mid , pos , val);
        update(id << 1 | 1 , mid + 1 , r , pos , val);
        sg[id] = min(sg[id << 1] , sg[id << 1 | 1]);
    }
    int get(int id , int l , int r , int u , int v){
        if (l > v || r < u){
            return 1e18;
        }
        if (l >= u && r <= v){
            return sg[id];
        }
        int mid = (l + r) >> 1;
        return min(get(id << 1 , l , mid , u , v) , get(id << 1 | 1 , mid + 1 , r , u , v));
    }
};
struct seg2{
    int sg[N << 2];
    int lazy[N << 2];

    void pushdown(int id){
        sg[id << 1] = max(sg[id << 1] , lazy[id]);
        sg[id << 1 | 1] = max(sg[id << 1 | 1] , lazy[id]);
        lazy[id << 1] = max(lazy[id << 1] , lazy[id]);
        lazy[id << 1 | 1] = max(lazy[id << 1 | 1] , lazy[id]);
        lazy[id] = 0;
    }

    void update(int id , int l , int r , int u , int v , int val){
        if (l > v || r < u){
            return;
        }

        if (l >= u && r <= v){
            sg[id] = max(sg[id] , val);
            lazy[id] = max(lazy[id] , val);
            return;
        }

        if (lazy[id]){
            pushdown(id);
        }
        int mid = (l + r) >> 1;
        update(id << 1 , l , mid , u , v , val);
        update(id << 1 | 1 , mid + 1 , r , u , v , val);
        sg[id] = max(sg[id << 1] , sg[id << 1 | 1]);
    }
    int get(int id , int l , int r , int u , int v){
        if (l > v || r < u){
            return 0;
        }
        if (l >= u && r <= v){
            return sg[id];
        }
        if (lazy[id]){
            pushdown(id);
        }
        int mid = (l + r) >> 1;
        return max(get(id << 1 , l , mid , u , v) , get(id << 1 | 1 , mid + 1 , r , u , v));
    }
};

namespace subac{
    int MOD2 = ltn(2 , mod - 2);
    int G(int u , int v){
        return ((u % mod * ((u + 1) % mod)) % mod * MOD2 % mod) * ((v % mod * ((v + 1) % mod)) % mod * MOD2 % mod) % mod;
    }

    static seg sg;
    static int ans , rong[N];

    void xuli(int l , int r , int dc){
        int cc = sg.get(1 , 1 , n , l , r);
        int cr = rong[r] - rong[l - 1];
        ans = (ans + G(cc , cr) - G(dc , cr) + mod) % mod;
        int _l = 1 , _r = 0;
        FOR(i , l , r){
            if (h[i] > cc){
                if (_r - _l >= 0){
                    _r = i;
                }
                else{
                    _l = i;
                    _r = i;
                }
            }
            else{
                if (_r - _l >= 0){
                    xuli(_l , _r , cc);
                }
                _l = 1;
                _r = 0;
            }
        }
        if (_r - _l >= 0){
            xuli(_l , _r , cc);
        }
    }

    void solve(){
        FOR(i , 1 , n){
            sg.update(1 , 1 , n , i , h[i]);
            rong[i] = rong[i - 1] + w[i];
        }
        xuli(1 , n , 0);
        cout << ans;
    }
}

namespace subac2{
    int MOD2 = ltn(2 , mod - 2);
    int G(int u , int v){
        return ((u % mod * ((u + 1) % mod)) % mod * MOD2 % mod) * ((v % mod * ((v + 1) % mod)) % mod * MOD2 % mod) % mod;
    }

    static seg2 sg;
    static int ans , rong[N];

    stack<int> st;
    int l[N] , r[N];
    ii A[N];

    void solve(){
        FOR(i , 1 , n){
            rong[i] = rong[i - 1] + w[i];
            A[i].fs = h[i];
            A[i].sd = i;
            while(!st.empty() && h[st.top()] > h[i]){
                r[st.top()] = i - 1;
                st.pop();
            }
            if (st.empty()){
                l[i] = 1;
            }
            else{
                l[i] = st.top() + 1;
            }
            st.push(i);
        }
        while(!st.empty()){
            r[st.top()] = n;
            st.pop();
        }

        sort(A + 1 , A + 1 + n);

        FOR(i , 1 , n){
            int H = A[i].fs;
            int vt = A[i].sd;
            int take = sg.get(1 , 1 , n , l[vt] , r[vt]);
            if (H > take){
                ans = (ans + G(H , rong[r[vt]] - rong[l[vt] - 1]) - G(take , rong[r[vt]] - rong[l[vt] - 1]) + mod) % mod;
                sg.update(1 , 1 , n , l[vt] , r[vt] , H);
            }
        }

        cout << ans;
    }
}

signed main(){quick

    if(fopen("FENCE.inp", "r")){
        freopen("FENCE.inp", "r", stdin);
        freopen("FENCE.out", "w", stdout);
    }

    cin >> n;

    int cksub2 = 1;
    int cksub3 = 1;
    FOR(i , 1 , n){
        cin >> h[i];
        if (i > 1 && h[i] != h[i - 1]){
            cksub2 = 0;
        }
        if (i > 1 && h[i] < h[i - 1]){
            cksub3 = 0;
        }
    }
    FOR(i , 1 , n){
        cin >> w[i];
    }

    if (cksub2){
        sub2::solve();
        return 0;
    }
    if (cksub3){
        sub3::solve();
        return 0;
    }
    if (n <= 1000){
        subac::solve();
        return 0;
    }
    subac2::solve();
}

Compilation message (stderr)

fancyfence.cpp: In function 'int main()':
fancyfence.cpp:244:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  244 |         freopen("FENCE.inp", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
fancyfence.cpp:245:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  245 |         freopen("FENCE.out", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
#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...