首页 > 其他分享 >CF1909C Heavy Intervals 题解

CF1909C Heavy Intervals 题解

时间:2024-04-10 17:33:20浏览次数:26  
标签:Heavy 题解 ll tree CF1909C RL rl include order

一种似乎更抽象的解法?

题面

正文

看这道题,给定序列 \(l,r,c\),要求重构 \(l,r,c\) 使得 \(\sum_{i=1}^n(r_i-l_i) \times c_i\) 最小。

首先可以想到的就是尽量让小的 \(r_i-l_i\) 乘上大的 \(c_i\)。这样子看来 \(c_i\) 几乎不需要更多的处理,仅需从小到大(或从大到小)排个序。

来看如何求出优秀的 \(r_i-l_i\)。

对于每一个 \(r_i-l_i\),要使它们的差最小,最好的方法自然是使这两个数尽可能地相近并且 \(l_i<r_i\) 仍成立。因为题目中保证了初始序列的 \(l\) 与 \(r\) 满足 \(l_i<r_i\)。所以不存在构造不出满足目标的 \(l,r\) 序列。

假设已经找出了 \(n\) 个最优的 \(r_i-l_i\),分别是 \(rl_1,rl_2 \sim rl_n\)。将它们展开后再合并会发现,无论 \(rl_i\) 的具体值是什么,始终会满足:

\[\sum _{i=1}^n rl_i=\sum_{j=1}^n r_j - \sum _{k=1}^n l_k \]

说明在保证 \(rl\) 的选择最优的情况下,不管怎么排列并不会影响最终结果。这应该是显而易见的。

贪心的考虑一下,对于每个 \(r_i\),找到比它小的最大的 \(l_j\) 匹配,得到的 \(rl\) 即是最小。若有多个 \(r\) 匹配同一个 \(l\)。则让最小的 \(r\) 匹配(能小则小)。

下面内容过于抽象所以请移步其它题解

由于最近再练平衡树,练得脑子有点抽,诶?\(l_i,r_i\) 互不相同。比 \(r_i\) 小的最大值?于是自然而然地用到了三棵平衡树,来维护上面的 \(r,l\) 以及 \(rl\)。并且自己又非常懒惰,所以使用了 pb_ds

头文件:

#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>//平衡树
using namespace __gnu_pbds;

定义:

tree<ll , null_type , std::less<ll> , rb_tree_tag , tree_order_statistics_node_update> L , R;
tree<pair<ll , ll> , null_type , std::less<pair<ll , ll>> , rb_tree_tag , tree_order_statistics_node_update> RL;

在代码中用了如下操作:

  1. insert 插入一个数。代码内使用 L.insert(l)

  2. erase 擦除一个数或迭代器。代码内使用 L.erase(nl)

  3. lower_bound 返回指向首个不小于给定键的元素的迭代器。代码内使用 ll nl = *(--L.lower_bound(nr));(注:自减操作是为了找到比 \(nr\) 小的最大值)。

  4. order_of_key(x) 返回 \(x\) 以比较的排名。代码内使用 ll order = RL.order_of_key({rl , 0});

  5. find_by_order(x) 返回的排名 \(x\) 所对应元素的迭代器。代码内使用 ll rl = RL.find_by_order(0) -> first;

当然,功能多多,码量远小于手写平衡树只是比赛时没什么用

最后代码复杂度 \(O(Tn \log n)\),勉强能看。

PS:魔怔人平衡树学傻了。

代码

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#define ll long long
#define fr(i , a , b) for(ll i = a ; i <= b ; ++i)
#define fo(i , a , b) for(ll i = a ; i >= b ; --i)
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>//平衡树
using namespace __gnu_pbds;
using namespace std;
tree<ll , null_type , std::less<ll> , rb_tree_tag , tree_order_statistics_node_update> L , R;
tree<pair<ll , ll> , null_type , std::less<pair<ll , ll>> , rb_tree_tag , tree_order_statistics_node_update> RL;
ll T , n , l , r , c[200005];
inline bool cmp(ll x , ll y)
{
    return x > y;
}
ll sum;
signed main()
{
    // freopen("in.in" , "r" , stdin);
    // freopen("out.out" , "w" , stdout);
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> T;
    while(T--)
    {
        ll idx = 0;
        cin >> n;
        fr(i , 1 , n)
        {
            cin >> l;
            L.insert(l);
        }
        fr(i , 1 , n)
        {
            cin >> r;
            R.insert(r);
        }
        fr(i , 1 , n)
        {
            cin >> c[i];
        }
        fr(i , 1 , n)
        {
            ll nr = *(R.find_by_order(0));
            ll nl = *(--L.lower_bound(nr));
            RL.insert({nr - nl , ++idx});
            L.erase(nl);
            R.erase(nr);
        }
        sort(c + 1 , c + n + 1 , cmp);
        sum = 0;
        fr(i , 1 , n)
        {
            ll rl = RL.find_by_order(0) -> first;
            sum += rl * c[i];
            ll order = RL.order_of_key({rl , 0});
            RL.erase(RL.find_by_order(order));
        }
        cout << sum << '\n';  
    }
    return 0;
}

标签:Heavy,题解,ll,tree,CF1909C,RL,rl,include,order
From: https://www.cnblogs.com/xhqdmmz/p/18126509

相关文章

  • GitHub问题解决新突破,复旦大学MAGIS框架大幅超越GPT-4
    获取本文论文,请关注公众号【AI论文解读】回复:&nbsp;论文解读引言:GitHub问题解决的挑战与LLMs的潜力在软件开发的演进过程中,解决GitHub仓库中出现的问题是一个复杂的挑战。这不仅涉及到新代码的加入,还要维护现有功能的稳定运行。大型语言模型(LLMs)在代码生成和理解方......
  • Air Conditioner 题解
    [AirConditioner]题意简述题目链接。给定一个整数\(n\),每秒钟可以选择使\(n\)增加\(1\)或减少\(1\)或不改变,有\(M\)个询问,对于第\(i\)个询问,给定\(t_i,l_i,r_i\),表示询问在第\(t_i\)秒时,是否有\(n\in[l_i,r_i]\)。如果能满足所有的询问,输出YES,否则输出NO。......
  • Codeforces-182E 题解
    Vasyahasrecentlyboughtsomelandanddecidedtosurrounditwithawoodenfence.Hewenttoacompanycalled"Woodenboard"thatproduceswoodenboardsforfences.Vasyareadinthecatalogofproductsthatthecompanyhasatitsdisposal\(......
  • 20240410每日一题题解
    20240410每日一题题解Problem一只小猴买了若干个桃子。第一天他刚好吃了这些桃子的一半,又贪嘴多吃了一个;接下来的每一天它都会吃剩余的桃子的一半外加一个。第\(n\)天早上起来一看,只剩下\(1\)个桃子了。请问小猴买了几个桃子?输入一个正整数\(n\),表示天数。输出小猴买了多......
  • 分享30个外贸常见的问题解答
    顶易四月海关众筹活动实时参与人数已达1835,剩余名额不多。33国海关数据仅需300,一年只卖一次,需要续费/新购请抓紧时间!1、客户:我不会再为这笔订单支付更多的费用,也不接受其他条款。外贸人:下周交货期如果你能找得到其他供货商的话,我们很乐意把生产了一半的货送到另外一个供货......
  • 启动应用程序出现ieui.dll找不到问题解决
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个ieui.dll文件(挑选合适的版本文件)把它放入......
  • 启动应用程序出现inetcomm.dll找不到问题解决
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个inetcomm.dll文件(挑选合适的版本文件)把它......
  • el-table(V 2.15.14)在使用树结构表格并且设置align = 'center'后 树结构层级不明显问
    开发中遇到的小问题:如图所示三个层级区分并不明显,用户体验差解决方案:自定义CSS:首先取消此列的align="center"然后插入以下代码(此CSS为更改图示第二列的样式如果是其它列请自己获取样式名称)//标题居中::v-deepth.el-table_1_column_2.is-leaf.el-table__cell{t......
  • [ABC348] Atcoder ABC 248 A~G 题解
    [ABC348]AtcoderABC248A~G题解A模拟B模拟,不卡精度。C模拟D注意,药不可以拿着,只可以在那个格子吃掉。这就意味着,我们无论何时到达某个点,到达的点的集合都是固定的。所以对于每个药店跑BFS,然后看起点到终点是否连通即可。intn,m,k,ad[N][N],f[N][N],in[N][N],......
  • 20240409每日一题题解
    20240409每日一题题解Problem给你一个数组nums和一个值val,你需要原地移除所有数值等于val的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用O(1)额外空间并原地修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。So......