Cod sursa(job #3179869)

Utilizator AnSeDraAndrei Sebastian Dragulescu AnSeDra Data 4 decembrie 2023 13:26:05
Problema Arbori de intervale Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.44 kb
#include <fstream>
#include <stack>

using namespace std;

const int Nmax = 100005;
const int MOD = 1000000007;

int v[Nmax];
int uemm[Nmax], prev_emm[Nmax];
stack<int> st;

int main(){
    ifstream fin("leftmax.in");
    ofstream fout("leftmax.out");

    int n, left_distance, right_distance, dif;
    long long sol;

    fin >> n;
    for(int i = 1; i <= n; i++){
        fin >> v[i];
    }

    for(int i = n; i >= 1; i--){
        while(!st.empty() && v[st.top()] < v[i]){
            prev_emm[st.top()] = i;
            st.pop();
        }
        st.push(i);
    }
    while(!st.empty()){
        prev_emm[st.top()] = 0;
        st.pop();
    }

    for(int i = 1; i <= n; i++){
        while(!st.empty() && v[st.top()] < v[i]){
            uemm[st.top()] = i;
            st.pop();
        }
        st.push(i);
    }
    while(!st.empty()){
        uemm[st.top()] = n + 1;
        st.pop();
    }

    sol = 0;
    for(int i = 1; i <= n; i++){
        left_distance = i - prev_emm[i] - 1;
        right_distance = uemm[i] - i;

        if(left_distance >= right_distance){
            sol = (sol + 1LL * right_distance * (right_distance + 1) / 2) % MOD;
        }
        else{
            dif = right_distance - left_distance - 1;
            sol = (sol + 1LL * (1LL * right_distance * (right_distance + 1) - 1LL * dif * (dif + 1)) / 2) % MOD;
        }
    }

    fout << sol;

    return 0;
}