zoukankan      html  css  js  c++  java
  • 线段树维护单调栈

    例题

    淘淘摘苹果

    讲解

    • 由于单调栈在维护时,左儿子会对右儿子有影响,所以有一个 calc 函数,我的 calc 函数传入两个参数,rt 和 val,有一下三种情况
      • 如果左儿子的最大值大于 val,那么直接递归左儿子,然后加上右儿子的贡献,因为右儿子的最小值一定大于左儿子的最大值,这是在建树 pushup 时保证的。
      • 否则直接递归右儿子,因为左儿子在这时候一定是不满足的,就直接递归右儿子就行。(因为要找的是以val开始的上升序列长度)
      • 到叶子节点判断一下和 val 的大小就行。
    • pushup 的时候用左儿子和谐一下右儿子,保证单调性。

    code

    #include <bits/stdc++.h>
    using namespace std;
    inline int read() {
        int k = 0, f = 1; char ch = getchar();
        for (; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
        for (; isdigit(ch); ch = getchar()) k = k * 10 + ch - '0';
        return k * f;
    }
    const int maxn = 4e5 + 100; 
    int h[maxn];
    int n, m;
    struct node { int l, r, maxx, len; } t[maxn];
    #define tl t[rt].l
    #define tr t[rt].r
    #define ls (rt << 1)
    #define rs (rt << 1 | 1)
    int calc(int rt, int val) {
        if (tl == tr) return t[rt].maxx > val;
        if (t[ls].maxx > val) return calc(ls, val) + t[rs].len;
        else return calc(rs, val);
    }
    void pushup(int rt) {
        t[rt].maxx = max(t[ls].maxx, t[rs].maxx);
        t[rs].len = calc(rs, t[ls].maxx);
    }
    void build(int rt, int l, int r) {
        tl = l, tr = r;
        if (l == r) return t[rt].maxx = h[l], void();
        int mid = (l + r) >> 1;
        build(ls, l, mid), build(rs, mid + 1, r);
        pushup(rt);
    }
    void modify(int rt, int pos) {
        if (tl == tr) return t[rt].maxx = h[pos], void();
        int mid = (tl + tr) >> 1;
        if (pos <= mid) modify(ls, pos);
        else modify(rs, pos);
        pushup(rt);
    }
    int main() {
    #ifdef debug
    #else
        freopen("taopapp.in", "r", stdin);
        freopen("taopapp.out", "w", stdout);
    #endif
        n = read(), m = read();
        for (int i = 1; i <= n; i++) h[i] = read();
        build(1, 1, n);
        while (m--) {
            int pos = read(), val = read(), tmp = h[pos];
            h[pos] = val;
            modify(1, pos);
            printf("%d
    ", calc(1, -1));
            h[pos] = tmp;
            modify(1, pos);
        }
        return 0;
    }
    
  • 相关阅读:
    UVA 11174 Stand in a Line,UVA 1436 Counting heaps —— (组合数的好题)
    UVA 1393 Highways,UVA 12075 Counting Triangles —— (组合数,dp)
    【Same Tree】cpp
    【Recover Binary Search Tree】cpp
    【Binary Tree Zigzag Level Order Traversal】cpp
    【Binary Tree Level Order Traversal II 】cpp
    【Binary Tree Level Order Traversal】cpp
    【Binary Tree Post order Traversal】cpp
    【Binary Tree Inorder Traversal】cpp
    【Binary Tree Preorder Traversal】cpp
  • 原文地址:https://www.cnblogs.com/hellohhy/p/13802812.html
Copyright © 2011-2022 走看看