首页 > 其他分享 >洛谷题单指南-线段树的进阶用法-P4602 [CTSC2018] 混合果汁

洛谷题单指南-线段树的进阶用法-P4602 [CTSC2018] 混合果汁

时间:2025-01-22 17:10:06浏览次数:1  
标签:进阶 int 洛谷题 sum tr P4602 mid 果汁 美味

原题链接:https://www.luogu.com.cn/problem/P4602

题意解读:在一堆果汁中选出若干果汁,使得最小的美味度最大,且总体价格小于等于g,总体体积大于L,求这个最大的美味度。

解题思路:

显然,应该对答案进行二分,二分到一个美味度x,那么接下来check()函数要做的事,就是在所有美味度>=x的果汁中,

查询出取到体积L时所需要付出的总价格sum,只要sum<=g并且所有美味度>=x的果汁的总可用体积<=L,则check结果为true,继续找更大的美味度。

查询的时候,可以使用贪心策略,为了不超总价,显然价格越低的越应该优先选择。

如何在美味度>=x的果汁查询正好取到体积L的果汁总价格,并且还优先差价格小的呢?可以借助权值线段树!

用果汁价格作为权值,果汁能取的体积作为权值的数量cnt,然后维护区间所有果汁的总价格sum,就可以计算权值数量前L小的果汁总价格,

这里可以参考:https://www.cnblogs.com/jcwy/p/18674205

由于要实现在所有比美味度x大的果汁中查询,可以用可持久化线段树,将果汁按美味度从大到小排序,root[i]线段树就是维护所有美味度大于i位置美味度的果汁情况,对位置进行二分即可。

100分代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 100005;
typedef long long LL;

struct Juice
{
    int d, p, l;
    bool operator < (const Juice &j)  const &
    {
        return d > j.d;
    }
} a[N];

struct Node
{
    int L, R;
    LL cnt; //区间所有可用体积之和
    LL sum; //区间所有可用果汁价格之和
} tr[N * 80];
int root[N], idx;
LL g, L;
int n, m;

//基于根为pre的线段树复制,并将值为v的cnt加上num,并更新相应的sum
int update(int pre, int l, int r, int v, int num)
{
    int u = ++idx;
    tr[u] = tr[pre];
    tr[u].cnt += num;
    tr[u].sum += 1ll * v * num;
    if(l == r) return u;
    int mid = l + r >> 1;
    if(v <= mid) tr[u].L = update(tr[pre].L, l, mid, v, num);
    else tr[u].R = update(tr[pre].R, mid + 1, r, v, num);
    return u;
}

//在根为u的线段树中查询权值前k小的所有价格之和
LL query(int u, int l, int r, int k)
{
    if(l == r) return 1ll * l * k;
    int mid = l + r >> 1;
    LL leftcnt = tr[tr[u].L].cnt;
    if(leftcnt >= k) return query(tr[u].L, l, mid, k);
    else return tr[tr[u].L].sum + query(tr[u].R, mid + 1, r, k - leftcnt);
}

bool check(int x)
{
    LL res = query(root[x], 1, N, L);
    if(res <= g && tr[root[x]].cnt >= L) return true; //总价格<=g且可用的总体积>=L
    return false;
}

int main()
{
    cin >> n >> m;
    for(int i = 1; i <= n; i++) cin >> a[i].d >> a[i].p >> a[i].l;
    sort(a + 1, a + n + 1);

    for(int i = 1; i <= n; i++) root[i] = update(root[i - 1], 1, N, a[i].p, a[i].l);

    while(m--)
    {
        cin >> g >> L;
        int l = 1, r = n, ans = -1;
        while(l <= r)
        {
            int mid = l + r >> 1;
            if(check(mid)) ans = a[mid].d, r = mid - 1; //mid更小也就是美味度更大
            else l = mid + 1;
        }
        cout << ans << endl;
    }
    
    return 0;
}

 

标签:进阶,int,洛谷题,sum,tr,P4602,mid,果汁,美味
From: https://www.cnblogs.com/jcwy/p/18683708

相关文章

  • 挣脱代码枷锁,转型项目经理的进阶之路
    前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦......
  • 深入探索C#中Newtonsoft.Json库的高级进阶之路
    引言在C#开发的广袤天地中,数据的序列化与反序列化是构建高效、灵活应用程序的关键环节。而Newtonsoft.Json库,作为这一领域的璀璨明星,以其强大的功能和出色的性能,成为了众多开发者的首选工具......
  • Vue.js 进阶教程:深入理解 Vue 的功能和特性
    在上一篇教程中,我们学习了Vue.js的基础,掌握了如何创建Vue实例、如何使用数据绑定、以及如何处理简单的用户交互。在本篇教程中,我们将进一步探讨Vue.js的一些高级特性,帮助你构建更复杂的应用。1.Vue组件化开发Vue.js是一个基于组件的框架,组件是Vue应用的核心组......
  • 销售进阶:三步提问法,掌握客户心理
    在销售行业,时间就是金钱,我们必须争分夺秒地搞定客户。但也不能盲目行动,而要稳扎稳打。关键在于快速抓住客户需求,而客户往往不会主动透露他们的需求,甚至自己都不清楚自己想要什么。这就需要我们通过巧妙的提问来破局,否则忙活半天也只是白费力气。最让人头疼的是,跟客户扯了很久,却......
  • 宇树机器人G1宣布升级,「价格屠夫」内卷进阶
    近日,宇树科技宣布,宇树机器人G1仿生灵动功能升级。据介绍,本次宇树机器人G1主要升级了其行走及奔跑姿态,官方表示能做到「全球最柔顺的行走」。宇树机器人G1进化过程宇树机器人G1是宇树科技推出的一款人形机器人,2024年5月宇树发布G1。该机器人身高约127厘米,体重约35公斤,具......
  • 洛谷题单指南-线段树的进阶用法-P2839 [国家集训队] middle
    原题链接:https://www.luogu.com.cn/problem/P2839题意解读:求左端点在[a,b]之间,右端点在 [c,d]之间的子区间中,最大的中位数。解题思路:1、直男暴力法枚举左、右端点,然后排序计算中位数,这样的复杂度在n*n*logn,显然不可行。2、渣男巧妙法首先,要重新来看待何为中位数。设一段......
  • SQL进阶实战技巧:用户会话内行为模式挖掘
    目录0问题描述 1数据准备2问题分析3小结 往期精彩0问题描述分析用户在每个会话内的行为序列,找出最常见的前N种行为模式,并按用户分群。用户表结构和数据假设有名为user_behavior_log的用户行为日志表,包含以下字段:字段名数据类型描述user_idINT用户IDbehav......
  • Markdown转Beamer进阶
    技术背景在前面的一篇文章中,我们介绍过Markdown转Beamer的基本方法。通过这个方案,我们可以只写普通的Markdown文档,甚至可以用Github或者Gitee进行保存和协同编辑。然后在本地环境中通过pandoc进行编译构建,最终可以生成一个Beamer风格的pdf文件。这里我们不讨论到底是用PPT写比较......
  • Python进阶:深入理解import机制与importlib的妙用
    目录一、Pythonimport机制概述1.1import语句的基本用法1.2模块缓存机制1.3导入搜索路径1.4导入钩子和查找器二、importlib的妙用2.1动态模块导入2.2使用importlib实现插件系统2.3重新加载模块三、总结在Python编程的世界里,import语句是开发者最常用的工......
  • JS宏进阶:正则表达式的使用
    正则表达式,对于任何一门编程语言来说,都是一种非常强大的工具,主要用于搜索、编辑或操作文本和数据。因此,在JS中,也存在相应的对象newRegExp(),在本章中,将详细介绍正则表达式在JS宏中的运用。一、正则表达式的创建在基础篇章中,曾提及正则表达式对象,在JS中有两种创建方法,示例如......