1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| #include<bits/stdc++.h>
using namespace std;
template<typename T>void read(T&x){x=0;int fl=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') fl=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}x*=fl;} template<typename T,typename...Args>inline void read(T&t,Args&...args){read(t);read(args...);}
typedef long long LL; typedef vector<int> vi; typedef pair<int, int> pii; #define mp(x, y) make_pair(x, y) #define pb(x) emplace_back(x)
const int N = 300005; const LL INF = 1e14;
int n, h[N]; LL b[N], dp[N]; vector<pii> v;
struct segTree{ int l, r; LL dp, dpb, lazyb; }tr[N<<2]; #define lid id<<1 #define rid id<<1|1 #define mid ((tr[id].l + tr[id].r) >> 1) inline void pushup(int id){ tr[id].dp = max(tr[lid].dp, tr[rid].dp); tr[id].dpb = max(tr[lid].dpb, tr[rid].dpb); } inline void pushdown(int id){ if(tr[id].l == tr[id].r) return; if(tr[id].lazyb != -INF){ tr[lid].dpb = tr[lid].dp + tr[id].lazyb; tr[lid].lazyb = tr[id].lazyb; tr[rid].dpb = tr[rid].dp + tr[id].lazyb; tr[rid].lazyb = tr[id].lazyb; tr[id].lazyb = -INF; } } void build(int id, int l, int r){ tr[id].l = l, tr[id].r = r; tr[id].dp = tr[id].dpb = 0; tr[id].lazyb = -INF; if(l == r){ tr[id].dpb = b[l]; return; } build(lid, l, mid), build(rid, mid+1, r); pushup(id); } void modify(int id, int l, int r, LL val){ if(l > r) return; pushdown(id); if(tr[id].l == l && tr[id].r == r){ tr[id].lazyb = val; tr[id].dpb = tr[id].dp + val; return; } if(r <= mid) modify(lid, l, r, val); else if(l > mid) modify(rid, l, r, val); else modify(lid, l, mid, val), modify(rid, mid+1, r, val); pushup(id); } void add(int id, int pos, LL val){ pushdown(id); if(tr[id].l == tr[id].r){ tr[id].dpb = tr[id].dpb - tr[id].dp + val; tr[id].dp = val; return; } if(pos <= mid) add(lid, pos, val); else add(rid, pos, val); pushup(id); } LL querydpb(int id, int l, int r){ if(l > r) return -INF; pushdown(id); if(tr[id].l == l && tr[id].r == r) return tr[id].dpb; if(r <= mid) return querydpb(lid, l, r); else if(l > mid) return querydpb(rid, l, r); else return max(querydpb(lid, l, mid), querydpb(rid, mid+1, r)); }
int main(){ read(n); build(1, 0, n); for(int i = 1; i <= n; i++) read(h[i]); for(int i = 1; i <= n; i++) read(b[i]), modify(1, i, i, b[i]); for(int i = 1; i <= n; i++){ dp[i] = -INF; while(!v.empty() && h[i] < v.back().second) v.pop_back(); v.pb(mp(i, h[i])); int l = 0, r = v.size() - 1; while(l < r){ int md = (l + r + 1) >> 1; if(v[md].second < h[i]) l = md; else r = md - 1; } int pos = v[l].second < h[i] ? v[l].first : 0;
modify(1, pos, i, b[i]); dp[i] = max(dp[i], querydpb(1, 0, i-1)); add(1, i, dp[i]); } printf("%lld\n", dp[n]); return 0; }
|