zoukankan      html  css  js  c++  java
  • 买房

    ps:和今年多校的某道题很像,只不过修改是永久的。正解没想出来,用线段树暴力搞出来的,5960ms。考虑线段树的节点维护两个信息:该区间的最大值,该区间以第一个元素为起点递增的最长序列的长度。那么问题在于每次更新后,怎么维护整个区间的递增序列长度(L),有一个很明显的想法,就是讨论左儿子和右儿子的最大值,如果左儿子的最大值大于右儿子的最大值,那么L = 左儿子的L,否则,就在右儿子所管辖的区间中找以左儿子的最大值为起点的最长递增序列,然后拼接一下就得到的整个区间的L。

    inline void upd(int &x, int y) { x < y && (x = y); }
    
    const int N = 100005;
    
    int n, m, sum[4 * N];
    double a[4 * N], Max[4 * N];
    
    int Find(int l, int r, int root, double x) {
        if (l == r) {
            return 1;
        }
        int mid = (l + r) >> 1;
        if (Max[lson] <= x) return Find(mid + 1, r, rson, x);
        return sum[root] - sum[lson] + Find(l, mid, lson, x);
    }
    
    void Pushup(int l, int r, int root) {
        if (Max[lson] >= Max[rson]) {
            sum[root] = sum[lson];
        }
        else {
            int mid = (l + r) >> 1;
            sum[root] = sum[lson] + Find(mid + 1, r, rson, Max[lson]);
        }
        Max[root] = max(Max[lson], Max[rson]);
    }
    
    void Update(int l, int r, int root, int pos, double x) {
        if (l == r) {
            a[root] = Max[root] = x;
            sum[root] = 1;
            return;
        }
        int mid = (l + r) >> 1;
        if (mid >= pos) Update(l, mid, lson, pos, x);
        else Update(mid + 1, r, rson, pos, x);
        Pushup(l, r, root);
    }
    
    
    int main()
    {
        BEGIN() {
            cin >> n >> m;
            mem(sum, 0);
            rep(i, 0, 4 * N) Max[i] = 0;
    
            Rep(i, 1, m) {
                int x, y;
                sc(x), sc(y);
                Update(1, n, 1, x, 1.0 * y / x);
                pr(sum[1]);
            }
        }
        return 0;
    }
  • 相关阅读:
    计算机网络复习(二) 应用层
    JavaScript实战笔记(二) 数组去重
    计算机网络复习(一) 基本介绍
    计算机网络复习
    Git学习笔记(一) 常用命令
    Git学习笔记
    Python实战笔记(三) 多线程
    Python实战笔记(二) 网络编程
    Python学习笔记
    XBox360自制系统的更新(Update)
  • 原文地址:https://www.cnblogs.com/zgglj-com/p/9527182.html
Copyright © 2011-2022 走看看