首页 > 其他分享 >962. 最大宽度坡(权值线段树, 权值树状数组)

962. 最大宽度坡(权值线段树, 权值树状数组)

时间:2023-10-19 17:55:20浏览次数:31  
标签:res 962 树状 int 权值 nums tree ans

 本题要快速找到某个数字在数组中左边<=它的数的最小下标。

可以建立一个权值线段树,nums[i]处维护最小下标。

class Solution {
public:

    const static int N = 50010, INF = 0x3f3f3f3f;

    struct Node {
        int l, r, v;
    } tr[N * 4];

    void pushup(int u) {
        tr[u].v = min(tr[u << 1].v, tr[u << 1 | 1].v);
    }

    void build(int u, int l, int r) {
        tr[u] = {l, r, INF};
        if(l == r) return;
        int mid = l + r >> 1;
        build(u << 1, l, mid);
        build(u << 1 | 1, mid + 1, r);
        pushup(u);
    }

    void update(int u, int x, int v) {
        if(tr[u].l == tr[u].r) {
            tr[u].v = min(tr[u].v, v);
            return;
        }
        int mid = tr[u].l + tr[u].r >> 1;
        if(x <= mid) update(u << 1, x, v);
        else update(u << 1 | 1, x, v);
        pushup(u);
    }

    int query(int u, int l, int r) {
        if(tr[u].l >= l && tr[u].r <= r) {
            return tr[u].v;
        }
        int res = INF;
        int mid = tr[u].l + tr[u].r >> 1;
        if(l <= mid) res = min(res, query(u << 1, l, r));
        if(r > mid) res = min(res, query(u << 1 | 1, l, r));
        return res;
    }

    int maxWidthRamp(vector<int>& nums) {
        int mx = *max_element(nums.begin(), nums.end()), n = nums.size();
        build(1, 0, mx);
        int ans = 0;

        for(int i = 0; i < n; i ++ ) {
            int p = query(1, 0, nums[i]);
            if(p < i) ans = max(ans, i - p);
            update(1, nums[i], i);
        }

        return ans;
    }
};

 

权值树状数组

class Solution:
    def maxWidthRamp(self, nums: List[int]) -> int:
        n, ans = len(nums), 0
        tree = [0x3f3f3f3f] * (int(5e4)+5)

        def update(u: int, v: int) -> None:
            while u < len(tree):
                tree[u] = min(tree[u], v)
                u += u & -u
        
        def query(u: int) -> int:
            res = tree[u]
            while u:
                res = min(res, tree[u])
                u -= u & -u
            return res

        for i, e in enumerate(nums):
            ans = max(ans, i - query(e + 1))
            update(e + 1, i)

        return ans

 

标签:res,962,树状,int,权值,nums,tree,ans
From: https://www.cnblogs.com/zk6696/p/17775281.html

相关文章

  • 【LCT、树状数组】CF1137F Matches Are Not a Child's Play
    哈人*3400,是不是贺过了个1F(?单点编号\(\tomax+1\),动态维护prufer序列删除了哪些点。看似不可做,但是不难发现我们一个点被更改其他点的相对次序不会改变,反而\(x\tomax\)这条链的删除次序到了最后面。然后我们以权值最大点为根,不难发现每次只是对根到该点的链更改了......
  • 树状数组
    数据结构,支持区间查询,单点修改或区间修改,单点查询。单点修改操作:voidmodify(intx,intval){ while(x<N){ c[x]+=val; x+=lowbit(x); }}查询前缀和:intquery(intx){ intres=0; while(x){ res+=c[x]; x-=lowbit(x); } returnres;}要做到区间修改、单......
  • 使用vue在移动端显示树状多选功能
    最近的项目要求是做一个树状的多选功能,然而该项目是使用vant4作为前端的框架,vant4只有树状单选,没有多选的,那只能自己写一个了。借鉴博主https://blog.csdn.net/m0_68428581/article/details/130641982,我将他的代码转成了vue3的语法,并且根据自己的项目需求进了相关改动,终于实现......
  • Slime Escape (CF D) (贪心, 双指针最大有效权值单调增长)
     补充:每次操作可以往左或者右走一步 思路:性质:以一边为重点使劲走,然后利用另外一边来给自己权值变大当这边要死了,就把这边回退到最大值,在走另一边,看另一边能到哪,这样每次都可以扩展最大值,于是利用双指针?也不是双指针,就是l,r分别贪心地向左和......
  • 树状数组模板
    namespaceBIT{ inttr[/*数据范围qwq*/],N; voidinit(intn){N=n;for(inti=1;i<=n;i++)tr[i]=0;} voidupdate(intx,inty){for(;x<=N;x+=(x&(-x)))tr[x]+=y;} intquery(intx){intres=0;for(;x;x-=(x&(-x......
  • 联合权值
    P1351[NOIP2014提高组]联合权值我们对于每个点计算它的子结点的\(\sumw,\maxw\)。如图,发现贡献有三类:直接计算。需要剔除自己这个点,对于sum直接减去即可,对于max维护一个次大值,发现这个点是最大值用次大值代替。枚举子节点,然后直接利用子节点的\(\sum,\max\)信......
  • NOIPTG联合权值
    P1351[NOIP2014提高组]联合权值我们对于每个点计算它的子结点的\(\sumw,\maxw\)。如图,发现贡献有三类:直接计算。需要剔除自己这个点,对于sum直接减去即可,对于max维护一个次大值,发现这个点是最大值用次大值代替。枚举子节点,然后直接利用子节点的\(\sum,\max\)信......
  • 笔记——树状数组
    蓝月の笔记——树状数组篇在可恶的OI里,我们尝尝会遇到一些区间问题,例如区间修改单点查询,单点修改区间查询,区间修改单点查询,单点修改单点查询。其中,单点修改区间查询,就是树状数组最经典的用法啦!Luogu-P3374给定一个长度为\(n\)的序列\(a_1,a_2,\cdots,a_n\)和两种操作:......
  • 高级数据结构--树状数组
    一维树状数组单点修改-区间查询输入32123120213输出6数据范围对于所有数据,\(1≤n,q≤10^6,∣a[i]∣≤10^6,1≤l≤r≤n,∣x∣≤10^6\)。点击查看代码#include<bits/stdc++.h>#defineIOSios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nu......
  • 权值线段树 学习笔记
    8月集训学了权值线段树,当时没怎么加强训练。国庆刚好开始有时间,巩固巩固。补上学习笔记。首先介绍权值树。其本质是一个记录每个数出现次数的线段树,也就是由桶建成的树。接下来介绍各种操作。1.插入。由于统计的是出现次数,从这个数往上依次加1即可。voidinsert(intx,int......