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

news2024/9/24 0:27:50

目录

一、题目

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;
				else
					hi = 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 DEBUG
		freopen("in.txt", "r", stdin);
		freopen("out.txt", "w", stdout);
	#endif
	
	int T = 1;
	// std::cin >> T;
	while (T --) {
		solve();
	}

	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2071257.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NYX靶机笔记

NYX靶机笔记 概述 VulnHub里的简单靶机 靶机地址&#xff1a;https://download.vulnhub.com/nyx/nyxvm.zip 1、nmap扫描 1&#xff09;主机发现 # -sn 只做ping扫描&#xff0c;不做端口扫描 nmap -sn 192.168.84.1/24 # 发现靶机ip为 MAC Address: 00:50:56:E0:D5:D4 (V…

文心快码(Baidu Comate)初体验

文心快码&#xff08;Baidu Comate&#xff09;初体验 1文心快码简介和安装&#xff1a;简要介绍文心快码&#xff08;Baidu Comate&#xff09;、安装方法、使用方法等&#xff1b; Baidu Comate 是由百度自主研发&#xff0c;基于文心大模型&#xff0c;结合百度丰富的编程现…

【数模修炼之旅】08 支持向量机模型 深度解析(教程+代码)

【数模修炼之旅】08 支持向量机模型 深度解析&#xff08;教程代码&#xff09; 接下来 C君将会用至少30个小节来为大家深度解析数模领域常用的算法&#xff0c;大家可以关注这个专栏&#xff0c;持续学习哦&#xff0c;对于大家的能力提高会有极大的帮助。 1 支持向量机模型…

C++ TinyWebServer项目总结(10. 信号)

信号是由用户、系统、进程发送给目标进程的信息&#xff0c;以通知目标进程某个状态的改变或系统异常。Linux信号可由以下条件产生&#xff1a; 对于前台进程&#xff0c;用户可通过输入特殊终端字符来给它发送信号&#xff0c;如输入CtrlC通常会给进程发送一个中断信号。系统…

学习笔记 韩顺平 零基础30天学会Java(2024.8.24)

P532 Map接口特点2 P533 Map接口方法 P534 Map六大遍历方式 方法一&#xff1a;通过KeySet()&#xff0c;取出所有的Key&#xff0c;把取出的Key放到Set中&#xff0c;再通过Key取出对应的Value 到这里又有两种方式遍历Set&#xff1a;迭代器、增强for 方法二&#xff1a;通过v…

svn使用教程学习

如何撤销未提交的本地修改&#xff1f; 点击svn提交&#xff0c;双击文件&#xff0c;可以查看准备提交的修改内容。 如何撤销已经提交的内容&#xff1f; 选择‘复原此版本做出的修改’&#xff1a; 但是&#xff0c;这个只是复原在本地了&#xff0c;我们需要提交上去&…

pycharm远程调试服务器代码提示,运行‘test’时出错,illegal char at index

pycharm远程调试服务器代码提示&#xff0c;运行‘test’时出错&#xff0c;illegal char at index &#xff0c;illegal char at index 0:4ba0d3dd-ad57-46cb-83d6-dc4e2d307520>/DETR/test.py 并不是在pycharm的右侧remote Host选择服务器上的文件&#xff0c;然后点击执行…

R6RS标准之重要特性及用法实例(三十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列…

java计算机毕设课设—企业电子投票系统(附源码、文章、相关截图、部署视频)

这是什么系统&#xff1f; java计算机毕设课设—企业电子投票系统(附源码、文章、相关截图、部署视频) 企业电子投票系统是一款高效便捷的在线投票平台包括前端普通用户和后端管理员两大模块&#xff0c;普通用户可登录投票、查看结果&#xff0c;管理员则负责后台管理&#…

利用 Windows CryptoAPI 中的关键欺骗漏洞

背景 三个月前,在我们 2022 年 10 月补丁星期二分析中,我们分享了 Windows CryptoAPI 中一个严重欺骗漏洞 CVE-2022-34689 的基本描述。据微软称,此漏洞允许攻击者“欺骗其身份并以目标证书的身份执行身份验证或代码签名等操作”。 CryptoAPI 是 Windows 中用于处理与加密…

IEEE T-ASLP | 利用ASR预训练的Conformer模型通过迁移学习和知识蒸馏进行说话人验证

近期&#xff0c;昆山杜克大学在语音旗舰期刊 IEEE/ACM Transactions on Audio, Speech and Language Processing (TASLP)上发表了一篇题为“Leveraging ASR Pretrained Conformers for Speaker Verification Through Transfer Learning and Knowledge Distillation”的论文。论…

Wireshark Lab: TCP v7.0

Wireshark Lab: TCP v7.0 1. Capturing a bulk TCP transfer from your computer to a remote server 步骤 打开浏览器&#xff0c;在url中输入http://gaia.cs.umass.edu/wiresharklabs/alice.txt &#xff0c;然后右键点击另存为下载文本。 访问http://gaia.cs.umass.edu/w…

【JVM】类加载器、双亲委派、SPI(一)

类加载器、双亲委派、SPI 类加载器 JVM中有两种类型的类加载器&#xff0c;由C编写的及由Java编写的。除了启动类加载器(BootstrapClassLoader)是由C编写的&#xff0c;其他都是由Java编写的&#xff0c;由Java编写的类加载器都继承自类java.lang.ClassLoader.JVM还支持自定义…

父子进程资源问题+vfork

一、从内存的角度分析父子进程资源问题 父子进程在内存资源使用上既共享又独立。它们通过写时复制技术实现地址空间的共享&#xff0c;但在修改数据时各自维护独立副本。代码段共享以节省内存&#xff0c;同时继承并打开的文件描述符等系统资源需注意同步和互斥问题。这种特殊…

Linux云计算 |【第二阶段】SECURITY-DAY1

主要内容&#xff1a; 监控基础&#xff08;系统监控命令、监控软件&#xff09;、Zabbix监控服务端部署、Zabbix监控客户端部署、创建监控主机、调用监控模板、自定义key、创建模板、应用集、监控项、绑定模板&#xff1b; 一、监控概述 1&#xff09;监控的目的 ① 实时报…

解决雪崩的方案之一:流量控制

​​​​​​​ 1.簇点链路 2.设置流控模式 2.1设置直接流控模式 2.2.设置关联流控模式 2.3设置链路流控模式 2.4总结 3.设置流控效果 3.1warm up 预热模式 3.2排队等待 3.3总结 4.热点参数限流 4.1全局参数限流 4.2热点参数限流 解决雪崩的方案之一&#xff1a;…

基于SpringBoot的银行OA系统设计与实现

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot架构&#xff0c;前端使用H5、CSS3、JS和DIV技术 工具&#xff1a;MyEclipse、Navicat f…

种树问题——CSP-J1真题讲解

【题目】 小明在某一天中依次有七个空闲时间段&#xff0c;他想要选出至少一个空闲时间段来练习唱歌&#xff0c;但他希望任意两个练习的时间段之间都有至少两个空闲的时间段让他休息。则小明一共有( ) 种选择时间段的方案 A. 31 B. 18 C. 21 D. 33 【答案】 B 【解析…

前端(Vue)headerSearch(页面搜索)通用解决方案 及 原理

简介 击后弹出输入框输入框可以输入页面的索引&#xff0c;比如项目中包含了文章相关的点击后可以进入对应界面同时也支持英文索引 原理 headerSearch 是复杂后台系统中非常常见的一个功能&#xff0c;它可以&#xff1a;在指定搜索框中对当前应用中所有页面进行检索&#…

stm32MX+freertos在创建task时,选项的含义

任务名称&#xff08;Task Name&#xff09;&#xff1a; 用于标识任务的名称&#xff0c;便于调试和日志记录。 优先级&#xff08;Priority&#xff09;&#xff1a; 任务的执行优先级。FreeRTOS支持多个优先级&#xff0c;高优先级的任务会优先于低优先级的任务执行。 堆栈…