当前位置: 首页 > news >正文

线段树+二分,CF 431E - Chemistry Experiment

目录

一、题目

1、题目描述

2、输入输出

2.1输入

2.2输出

3、原题链接

二、解题报告

1、思路分析

2、复杂度

3、代码详解


一、题目

1、题目描述

2、输入输出

2.1输入

2.2输出

3、原题链接

431E - Chemistry Experiment


二、解题报告

1、思路分析

贪心的考虑,如何加水可以让有水的瓶子的最大值最小?

选取一个上界top,低于top的瓶子我们先加到top,然后剩余的水平均加到这几个值为top的瓶子中

为了便于描述上述过程,我们不妨将瓶子的值非降序排序,记为val

那么每次相当于选择一个k,把h[0, k] 调整为h[k],多出来的水,平均给0~k这些瓶子

如果这是最优解,那么 (k + 1) * h[k] - sum(h{0, k}) <= v <= (k + 2) * h[k + 1] - sum(h(0l, k + 1))

令B[i] = (k + 1) * h[k] - um(h{0, k}),显然B[i] 单调递增,那么我们对于每个操作2,二分位置即可

B序列可以用线段树维护

2、复杂度

时间复杂度: O(nlogn + q log^2 n)空间复杂度:O(n + q)

3、代码详解

 ​
#include <bits/stdc++.h>using i64 = long long;
using i32 = unsigned int;
using u64 = unsigned long long;
using i128 = __int128;constexpr int inf32 = 1E9 + 7;
constexpr i64 inf64 = 1E18 + 7;
constexpr int P = 998'244'353;template<class Info>
struct SegmentTree {int n;std::vector<Info> info;SegmentTree(int _n): n(_n), info(2 << (32 - __builtin_clz(_n))) {}template<class T>SegmentTree(std::vector<T>& _init): SegmentTree(_init.size()) {auto build = [&](auto&& self, int p, int l, int r) {if (l == r) {info[p] = _init[l];return;}int mid = l + r >> 1;self(self, p << 1, l, mid), self(self, p << 1 | 1, mid + 1, r);pull(p);};build(build, 1, 0, n - 1);}void pull(int p) {info[p] = info[p << 1] + info[p << 1 | 1];}void modify(int p, int l, int r, int x, const Info& v) {if (l == r) {info[p] = v;return;}int mid = l + r >> 1;if (x <= mid) modify(p << 1, l, mid, x, v);else modify(p << 1 | 1, mid + 1, r, x, v);pull(p);}void modify(int x, const Info& v) {modify(1, 0, n - 1, x, v);}Info rangeQuery(int p, int l, int r, int x, int y) {if (l > y || r < x) return Info();if (x <= l && r <= y) {return info[p];}int mid = l + r >> 1;return rangeQuery(p << 1, l, mid, x, y) + rangeQuery(p << 1 | 1, mid + 1, r, x, y);}Info rangeQuery(int l, int r) {return rangeQuery(1, 0, n - 1, l, r);}
};struct Info{i64 s = 0;int val = 0, sz = 0;friend Info operator+ (const Info &a, const Info &b) {if (!a.sz) return b;if (!b.sz) return a;return {a.s + b.s + 1LL * (b.val - a.val) * a.sz,b.val,a.sz + b.sz};}
};void solve() {int n, q;std::cin >> n >> q;std::vector<i64> h(n), val;for (int i = 0; i < n; ++ i)std::cin >> h[i], val.push_back(h[i]);std::vector<std::array<i64, 2>> o(q);for (int i = 0, op; i < q; ++ i) {std::cin >> op;if (op == 1) {std::cin >> o[i][0] >> o[i][1];-- o[i][0];val.push_back(o[i][1]);}else {o[i][0] = -1;std::cin >> o[i][1];}}std::ranges::sort(val);val.erase(std::unique(val.begin(), val.end()), val.end());std::map<i64, int> mp;std::vector<Info> info(val.size());for (int i = 0; i < val.size(); ++ i)mp[val[i]] = i, info[i].val = val[i];for (int x : h)++ info[mp[x]].sz;SegmentTree<Info> sgt(info);for (auto &[p, v] : o) {if (~p) {int i = mp[h[p]];-- info[i].sz;sgt.modify(i, info[i]);i = mp[h[p] = v];++ info[i].sz;sgt.modify(i, info[i]);}else {int lo = -1, hi = val.size();while (lo + 1 < hi) {int x = lo + hi >> 1;if (sgt.rangeQuery(0, x).s <= v)lo = x;elsehi = x;}auto t = sgt.rangeQuery(0, lo);std::cout << std::fixed << std::setprecision(10) << 1.0 * (v - t.s) / t.sz + t.val << '\n';}}}auto FIO = []{std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);return 0;
}();int main () {#ifdef DEBUGfreopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);#endifint T = 1;// std::cin >> T;while (T --) {solve();}return 0;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Verilog刷题笔记60
  • 计算机网络-PIM-SM组播实验
  • C++:病毒系列回归记3/3 (Doge智能系统已上线)
  • 如何使用查询路由构建更先进的 RAG
  • 宠物掉毛、有异味怎么办?怎么选择宠物空气净化器?
  • OpManager Plus简单说明以及在Linux下的安装
  • 四、控制结构
  • 网络协议的基础知识
  • 链表(静态/动态创建,遍历,计数,查找,在节点的前/后方插入新节点,头插法,尾插法)
  • 基于x86 平台opencv的图像采集和seetaface6的人脸检测功能
  • :class的用法及应用
  • java后端请求与响应总结
  • C++入门基础知识31
  • Vue解决父子组件传值,子组件改变值后父组件的值也改变的问题
  • WPF—Triggers触发器
  • [译]如何构建服务器端web组件,为何要构建?
  • 【面试系列】之二:关于js原型
  • 07.Android之多媒体问题
  • CoolViewPager:即刻刷新,自定义边缘效果颜色,双向自动循环,内置垂直切换效果,想要的都在这里...
  • Fabric架构演变之路
  • Git同步原始仓库到Fork仓库中
  • MySQL的数据类型
  • node.js
  • Python实现BT种子转化为磁力链接【实战】
  • session共享问题解决方案
  • Spring技术内幕笔记(2):Spring MVC 与 Web
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • 阿里云应用高可用服务公测发布
  • 读懂package.json -- 依赖管理
  • 如何设计一个比特币钱包服务
  • 通过npm或yarn自动生成vue组件
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • 翻译 | The Principles of OOD 面向对象设计原则
  • 蚂蚁金服CTO程立:真正的技术革命才刚刚开始
  • ​flutter 代码混淆
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • ​第20课 在Android Native开发中加入新的C++类
  • ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTr
  • #VERDI# 关于如何查看FSM状态机的方法
  • (007)XHTML文档之标题——h1~h6
  • (1)Jupyter Notebook 下载及安装
  • (rabbitmq的高级特性)消息可靠性
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (二)测试工具
  • (二)斐波那契Fabonacci函数
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (三十五)大数据实战——Superset可视化平台搭建
  • (四)事件系统
  • (未解决)macOS matplotlib 中文是方框
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • (正则)提取页面里的img标签
  • (转)memcache、redis缓存
  • *p++,*(p++),*++p,(*p)++区别?
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑