data structures dp graphs *2200

Please click on ads to support us..

Python Code:

import random
import sys
import os
import math
from bisect import bisect_left, bisect_right
from collections import Counter, defaultdict, deque
from functools import lru_cache, reduce
from itertools import accumulate, combinations, permutations
from heapq import nsmallest, nlargest, heapify, heappop, heappush
from io import BytesIO, IOBase
from copy import deepcopy

BUFSIZE = 4096
MAX = (1 << 63) - 1
MIN = -MAX


class Segment:
    def __init__(self, n):
        self.sgm_tree = [0 for i in range(2 * n)]
        self.d = {}

    def queries(self, l, r):
        count = 0
        while l <= r:
            if l % 2 == 1:
                count += self.sgm_tree[l]
                l += 1
            if r % 2 == 0:
                count += self.sgm_tree[r]
                r -= 1
            l = l >> 1
            r = r >> 1
        return count

    def update(self, indx, num):
        if num == 2:
            self.d[indx] -= 1
            if self.d[indx] == 0:
                self.sgm_tree[indx] = 0
        else:
            if indx not in self.d:
                self.d[indx] = 0
            self.d[indx] += 1
            if self.d[indx] == 1:
                self.sgm_tree[indx] = 1
        indx = indx >> 1
        while indx >= 1:
            self.sgm_tree[indx] = self.sgm_tree[2 * indx] + self.sgm_tree[2 * indx + 1]
            indx = indx >> 1


class FenwickTree:
    def __init__(self, n):
        self.n = n
        self.bit = [0] * n

    def sum(self, r):
        res = 0
        while r >= 0:
            res += self.bit[r]
            r = (r & (r + 1)) - 1
        return res

    def rsum(self, l, r):
        return self.sum(r) - self.sum(l - 1)

    def add(self, idx, delta):
        while idx < self.n:
            self.bit[idx] += delta
            idx = idx | (idx + 1)


def gcd(a, b):
    if a < 0: a = -a
    if b < 0: b = -b
    if a < b:
        a, b = b, a
    if a % b == 0:
        return b
    return gcd(b, a % b)


def toposort(graph):
    res, found = [], [0] * len(graph)
    stack = list(range(len(graph)))
    while stack:
        node = stack.pop()
        if node < 0:
            res.append(~node)
        elif not found[node]:
            found[node] = 1
            stack.append(~node)
            stack += graph[node]

        for node in res:
        if any(found[nei] for nei in graph[node]):
            return None
        found[node] = 0

    return res[::-1]


class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)


class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")


sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")


def I():
    return input()


def II():
    return int(input())


def MI():
    return map(int, input().split())


def LI():
    return list(input().split())


def LII():
    return list(map(int, input().split()))


def TMI(arr):
    return list(map(str, arr))


def GMI():
    return map(lambda x: int(x) - 1, input().split())


def LGMI():
    return list(GMI())


n = II()
h = LII()
dp = [0] * n
stka,stkb = [0],[0]
for i in range(1,n):
    dp[i] = dp[i - 1] + 1
    while stka and h[stka[-1]] >= h[i]:
        tmp = stka.pop()
        if h[tmp] > h[i] and stka:
            dp[i] = min(dp[i],dp[stka[-1]] + 1)
    while stkb and h[stkb[-1]] <= h[i]:
        tmp = stkb.pop()
        if h[tmp] < h[i] and stkb:
            dp[i] = min(dp[i],dp[stkb[-1]] + 1)
    stka.append(i)
    stkb.append(i)
print(dp[n - 1])



















C++ Code:

#include <bits/stdc++.h>
#define F first
#define S second

using namespace std;

using ll = long long;
using PI = pair<int, int>;
using PII = pair<PI, int>;

const int N = 3e5+1;
const int INF = 1e9+7;

int ST1[4*N];
int ST2[4*N];
int arr[N];

void build(int l, int r, int v){
    if(l == r){
        ST1[v] = arr[l];
        ST2[v] = arr[l];
        return;
    }
    int mid = (l + r)/2;
    build(l, mid, 2*v);
    build(mid+1, r, 2*v+1);
    ST1[v] = max(ST1[2*v], ST1[2*v+1]);
    ST2[v] = min(ST2[2*v], ST2[2*v+1]);

}

int ans = 0;

void query1(int l, int r, int ql, int qr, int k, char c, int v){
    if(l == r){
        assert(ans == 0);
        ans = l;
        return;
    }
    int mid = (l + r)/2;

    if(c == 'l'){
        if(ST1[2*v+1] >= k && mid+1 <= qr && r >= ql && !ans){
            query1(mid+1, r, ql, qr, k, c, 2*v+1);
        }
        if(ST1[2*v] >= k && l <= qr && mid >= ql && !ans){
            query1(l, mid, ql, qr, k, c, 2*v);
        }
    }
    else{
        if(ST1[2*v] >= k && l <= qr && mid >= ql && !ans){
            query1(l, mid, ql, qr, k, c, 2*v);
        }
        if(ST1[2*v+1] >= k && mid+1 <= qr && r >= ql && !ans){
            query1(mid+1, r, ql, qr, k, c, 2*v+1);
        }
    }

}

void query2(int l, int r, int ql, int qr, int k, char c, int v){
    if(l == r){
        assert(ans == 0);
        ans = l;
        return;
    }
    int mid = (l + r)/2;
    if(c == 'l'){
        if(ST2[2*v+1] <= k && mid+1 <= qr && r >= ql && !ans){
            query2(mid+1, r, ql, qr, k, c, 2*v+1);
        }
        if(ST2[2*v] <= k && l <= qr && mid >= ql && !ans){
            query2(l, mid, ql, qr, k, c, 2*v);
        }
    }
    else{
        if(ST2[2*v] <= k && l <= qr && mid >= ql && !ans){
            query2(l, mid, ql, qr, k, c, 2*v);
        }
        if(ST2[2*v+1] <= k && mid+1 <= qr && r >= ql && !ans){
            query2(mid+1, r, ql, qr, k, c, 2*v+1);
        }
    }
}

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0);

    int n; cin >> n;

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

    build(1, n, 1);

    vector<int> adjl[n+1];
    for(int i = 1; i <= n; i++){
        int l1 = 0, l2 = 0, r1 = 0, r2 = 0;

        if(i == 1){
            query2(1, n, i+1, n, arr[i], 'r', 1);
            r1 = ans;
            ans = 0;
            query1(1, n, i+1, n, arr[i], 'r', 1);
            r2 = ans;
            ans = 0;
        }
        else if(i == n){
            query2(1, n, 1, i-1, arr[i], 'l', 1);
            l1 = ans;
            ans = 0;
            query1(1, n, 1, i-1, arr[i], 'l', 1);
            l2 = ans;
            ans = 0;
        }
        else{
            query2(1, n, 1, i-1, arr[i], 'l', 1);
            l1 = ans;
            ans = 0;
            query1(1, n, 1, i-1, arr[i], 'l', 1);
            l2 = ans;
            ans = 0;
            query2(1, n, i+1, n, arr[i], 'r', 1);
            r1 = ans;
            ans = 0;
            query1(1, n, i+1, n, arr[i], 'r', 1);
            r2 = ans;
            ans = 0;
        }

        if(l1 != 0){
            adjl[l1].push_back(i);
        }
        if(l2 != 0){
            adjl[l2].push_back(i);
        }
        if(r1 != 0){
            adjl[i].push_back(r1);
        }
        if(r2 != 0 ){
            adjl[i].push_back(r2);
        }


     }
     queue<int> q;
     vector<bool> vis(n+1);
     vector<int> dis(n+1);
     vis[1] = 1;
     q.push(1);
     vector<int> parents(n+1);
     parents[1] = -1;
     while(!q.empty()){
         int v = q.front(); q.pop();

         for(auto i : adjl[v]){
            if(!vis[i]){
                vis[i] = 1;
                parents[i] = v;
                dis[i] = dis[v]+1;
                q.push(i);
            }
         }
     }
     cout << dis[n];



/*
33
47 864 7 44 132 71 16 3 5 11 132 32 1 132 78 21 8 131 8 1 456 48 4 54 8 13 46 13 156 6 1 1 1

10
1 2 1 1 1 1 1 1 2 1




*/






}


Comments

Submit
0 Comments
More Questions

816B - Karen and Coffee
838D - Airplane Arrangements
148B - Escape
847G - University Classes
1110A - Parity
1215B - The Number of Products
604C - Alternative Thinking
1204C - Anna Svyatoslav and Maps
322A - Ciel and Dancing
1689B - Mystic Permutation
1711B - Party
1702D - Not a Cheap String
1714F - Build a Tree and That Is It
1703F - Yet Another Problem About Pairs Satisfying an Inequality
610A - Pasha and Stick
1200A - Hotelier
1091A - New Year and the Christmas Ornament
1352B - Same Parity Summands
1102A - Integer Sequence Dividing
630B - Moore's Law
1004A - Sonya and Hotels
1680B - Robots
1690A - Print a Pedestal (Codeforces logo)
1295A - Display The Number
1077A - Frog Jumping
1714G - Path Prefixes
1369C - RationalLee
289B - Polo the Penguin and Matrix
1716A - 2-3 Moves
1670B - Dorms War