Cod sursa(job #2093897)

Utilizator andreicoman299Coman Andrei andreicoman299 Data 24 decembrie 2017 16:37:02
Problema Hashuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.58 kb
#include <bits/stdc++.h>
#define MAXN 200000

#define BUF_SIZE 1 << 14
char buf[BUF_SIZE];
int pbuf=BUF_SIZE;
FILE*fi,*fo;
inline char nextch(){
    if(pbuf==BUF_SIZE){
        fread(buf, BUF_SIZE, 1, fi);
        pbuf=0;
    }
    return buf[pbuf++];
}
inline int nextnum(){
    int a = 0;
    char c = nextch();
    while(!isdigit(c))
        c = nextch();
    while(isdigit(c)){
        a = a * 10 + c - '0';
        c = nextch();
    }
    return a;
}

class Aint{
    public:
    long long aint[4 * MAXN], lazy[4 * MAXN];
    int left, right;
    long long val, ans;

    void update(int p, int st, int dr){
        if(left <= st && dr <= right){
            lazy[p] = std::max(lazy[p], val);
            aint[p] = std::max(aint[p], lazy[p]);
            if(st != dr){
                lazy[2 * p] = std::max(lazy[2 * p], lazy[p]);
                lazy[2 * p + 1] = std::max(lazy[2 * p + 1], lazy[p]);
            }
            lazy[p] = 0;
        }
        else{
            lazy[2 * p] = std::max(lazy[2 * p], lazy[p]);
            lazy[2 * p + 1] = std::max(lazy[2 * p + 1], lazy[p]);
            lazy[p] = 0;

            int m = (st + dr) / 2;
            if(left <= m) update(2 * p, st, m);
            if(m + 1 <= right) update(2 * p + 1, m + 1, dr);

            aint[p] = std::max(std::max(aint[2 * p], lazy[2 * p]), std::max(aint[2 * p + 1], lazy[2 * p + 1]));
        }
    }
    void query(int p, int st, int dr){
        if(left <= st && dr <= right){
            aint[p] = std::max(aint[p], lazy[p]);
            if(st != dr){
                lazy[2 * p] = std::max(lazy[2 * p], lazy[p]);
                lazy[2 * p + 1] = std::max(lazy[2 * p + 1], lazy[p]);
            }
            lazy[p] = 0;
            ans = std::max(ans, aint[p]);
        }
        else{
            lazy[2 * p] = std::max(lazy[2 * p], lazy[p]);
            lazy[2 * p + 1] = std::max(lazy[2 * p + 1], lazy[p]);
            lazy[p] = 0;

            int m = (st + dr) / 2;
            if(left <= m) query(2 * p, st, m);
            if(m + 1 <= right) query(2 * p + 1, m + 1, dr);

            aint[p] = std::max(std::max(aint[2 * p], lazy[2 * p]), std::max(aint[2 * p + 1], lazy[2 * p + 1]));
        }
    }
}A1, A2;

int S[1 + MAXN];
long long D[1 + MAXN];

struct details{
    int firstpos;
    int minval;
    int pos;
} Q[1 + MAXN];
int next;
bool cmp(details A, details B){
    return A.firstpos > B.firstpos;
}

int main(){
    fi=fopen("hapsan.in","r");
    fo=fopen("hapsan.out","w");

    int n, m;
    n = nextnum();
    for(int i = 1; i <= n; i++)
        S[i] = nextnum();
    m = nextnum();
    for(int i = 1; i <= m; i++){
        A1.left = nextnum();
        A1.right = nextnum();
        A1.val = A1.right + 1;
        A1.update(1, 1, n);
    }

    for(int i = 1; i <= n; i++){
        A1.left = A1.right = i;
        A1.ans = 0;
        A1.query(1, 1, n);
        Q[i] = {A1.ans, S[i] + 1, i};
    }
    std::sort(Q + 1, Q + n + 1, cmp);
    next = 1;
    for(int i = n; i >= 1; i--){
        while(next <= n && Q[next].firstpos == i + 1){
            A2.left = Q[next].minval;
            A2.right = MAXN;
            A2.ans = 0;
            if(A2.left <= A2.right) A2.query(1, 1, MAXN);
            D[Q[next].pos] = A2.ans;
            next++;
        }
        A2.left = A2.right = S[i];
        A2.val = D[i] + S[i];
        A2.update(1, 1, MAXN);
    }
    A2.left = 1;
    A2.right = MAXN;
    A2.ans = 0;
    A2.query(1, 1, n);
    fprintf(fo,"%lld", A2.ans);

    fclose(fi);
    fclose(fo);
    return 0;
}