Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- #define fi first
- #define se second
- #define pb push_back
- #define pf push_front
- #define popb pop_back
- #define popf pop_front
- #define ins insert
- #define pq priority_queue
- #define minele min_element
- #define maxele max_element
- #define lb lower_bound //first pos >= val
- #define ub upper_bound // first pos > val
- #define cnt_bit __builtin_popcount
- #define debug(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
- //#pragma GCC optimize("Ofast")
- //#pragma GCC target("avx,avx2,fma")
- using namespace std;
- mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
- typedef long long ll;
- typedef pair<ll, ll> pll;
- typedef pair<int, int> pii;
- int d4x[4] = {1, 0, -1, 0}; int d4y[4] = {0, 1, 0, -1};
- int d8x[8] = {0, 1, 1, 1, 0, -1, -1, -1};
- int d8y[8] = {1, 1, 0, -1, -1, -1, 0, 1};
- const ll oo = 1e18;
- const ll maxN = 3e5 + 100;
- /* Author : Le Ngoc Bao Anh, 10A5, LQD High School for Gifted Student */
- void maximize(ll &a, ll b) {
- if(a < b) a = b;
- }
- void minimize(ll &a, ll b) {
- if(a > b) a = b;
- }
- ll Node[maxN * 4], Lazy[maxN * 4], dp[maxN];
- int L[maxN], R[maxN], L2[maxN], R2[maxN];
- ll a[maxN], b[maxN];
- ll rmq[maxN][18];
- void Down(int id) {
- ll x = Lazy[id]; Lazy[id] = -oo;
- maximize(Node[id * 2], x); maximize(Node[id * 2 + 1], x);
- maximize(Lazy[id * 2], x); maximize(Lazy[id * 2 + 1], x);
- }
- void Update(int L, int R, int lo, int hi, int id, ll x) {
- if(L > hi || R < lo) return;
- if(lo <= L && R <= hi) {
- maximize(Node[id], x);
- maximize(Lazy[id], x);
- return;
- }
- Down(id);
- int mid = (L + R) >> 1;
- Update(L, mid, lo, hi, id * 2, x);
- Update(mid + 1, R, lo, hi, id * 2 + 1, x);
- Node[id] = max(Node[id * 2], Node[id * 2 + 1]);
- }
- ll Get(int L, int R, int lo, int hi, int id) {
- if(L > hi || R < lo) return -oo;
- if(lo <= L && R <= hi) return Node[id];
- Down(id);
- int mid = (L + R) >> 1;
- return max(Get(L, mid, lo, hi, id * 2), Get(mid + 1, R, lo, hi, id * 2 + 1));
- }
- void solve() {
- int n; cin >> n;
- for(int i = 1; i <= n; i++) cin >> a[i];
- for(int i = 1; i <= n; i++) cin >> b[i];
- int g = 17;
- for(int i = 1; i <= n; i++) rmq[i][0] = b[i];
- for(int j = 1; j <= g; j++) {
- for(int i = 1; i <= n; i++) {
- if(i + (1 << j) - 1 > n) break;
- rmq[i][j] = max(rmq[i][j - 1], rmq[i + (1 << (j - 1))][j - 1]);
- }
- }
- stack<int> q;
- //cal L
- for(int i = 1; i <= n; i++) {
- while(!q.empty()) {
- if(b[q.top()] < b[i]) q.pop();
- else break;
- }
- if(!q.empty()) L[i] = q.top();
- q.push(i);
- }
- //cal R
- while(!q.empty()) q.pop();
- for(int i = n; i >= 1; i--) {
- while(!q.empty()) {
- if(b[q.top()] < b[i]) q.pop();
- else break;
- }
- if(!q.empty()) R[i] = q.top();
- else R[i] = n + 1;
- q.push(i);
- }
- auto get_max = [&](int L, int R) -> int {
- int len = (R - L + 1);
- int x = log2(len);
- return max(rmq[L][x], rmq[R - (1 << x) + 1][x]);
- };
- //Cal L2
- for(int i = 1; i <= n; i++) {
- if(!L[i]) continue;
- int lo = 1, hi = L[i] - 1;
- while(lo <= hi) {
- int mid = (lo + hi) >> 1;
- if(get_max(mid, L[i] - 1) > b[i]) {
- L2[i] = mid;
- lo = mid + 1;
- } else {
- hi = mid - 1;
- }
- }
- }
- //cal R2
- for(int i = 1; i <= n; i++) {
- if(R[i] > n) {
- R2[i] = n + 1;
- continue;
- }
- R2[i] = n + 1;
- int lo = R[i] + 1, hi = n;
- while(lo <= hi) {
- int mid = (lo + hi) >> 1;
- if(get_max(R[i] + 1, mid) > b[i]) {
- R2[i] = mid;
- hi = mid - 1;
- } else {
- lo = mid + 1;
- }
- }
- }
- for(int i = 1; i <= n; i++) dp[i] = -oo;
- for(int i = 1; i <= 4 * (n + 1); i++) Node[i] = Lazy[i] = -oo;
- Update(0, n, 0, 0, 1, 0);
- for(int i = 1; i <= n; i++) {
- dp[i] = Get(0, n, i, i, 1);
- ll g = -oo;
- if(L[i]) {
- g = Get(0, n, L2[i], L[i] - 1, 1);
- dp[i] = max(dp[i], g + a[i]);
- }
- ll x = Get(0, n, L[i], i - 1, 1);
- if(R[i] <= n) {
- Update(0, n, R[i], R2[i] - 1, 1, x + a[i]);
- }
- if(i <= R[i] - 2) Update(0, n, i + 1, R[i] - 1, 1, g + a[i]);
- Update(0, n, i, i, 1, dp[i]);
- }
- cout << dp[n];
- }
- int main()
- {
- ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
- // #ifndef ONLINE_JUDGE
- // freopen("input.txt", "r", stdin);
- // freopen("output.txt", "w", stdout);
- // #else
- // //online
- // #endif
- int tc = 1, ddd = 0;
- // cin >> tc;
- while(tc--) {
- //ddd++;
- //cout << "Case #" << ddd << ": ";
- solve();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement