首页 > 其他分享 >AtCoder Beginner Contest 287 G Balance Update Query

AtCoder Beginner Contest 287 G Balance Update Query

时间:2023-06-04 22:24:39浏览次数:48  
标签:rt AtCoder return Beginner Contest int res mid ql

洛谷传送门

AtCoder 传送门

线段树上二分入门题。

考虑一个贪心:每次询问按 \(a_i\) 从大到小选。正确性显然。

考虑动态开点线段树,每个结点 \(a_i \in [l, r]\) 存 \(\sum\limits_{a_i \in [l, r]} b_i\) 和 \(\sum\limits_{a_i \in [l, r]} a_i b_i\)。线段树上二分找到第一个 \(\sum\limits_{i = y}^{\infty} b_i > x\) 的 \(p\),那么 \(p + 1 \sim \infty\) 全选,\(p\) 选的数量根据还能选多少数而定。

时间复杂度 \(O((n + q) \log V)\)。

code
// Problem: G - Balance Update Query
// Contest: AtCoder - UNIQUE VISION Programming Contest 2023 New Year (AtCoder Beginner Contest 287)
// URL: https://atcoder.jp/contests/abc287/tasks/abc287_g
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 200100;
const int N = 1000000000;

int n, m, a[maxn], b[maxn];
ll sum[maxn << 7];
int rt, ntot, ls[maxn << 7], rs[maxn << 7], cnt[maxn << 7];

void update(int &rt, int l, int r, int x, ll y) {
	if (!rt) {
		rt = ++ntot;
	}
	cnt[rt] += y;
	sum[rt] += x * y;
	if (l == r) {
		return;
	}
	int mid = (l + r) >> 1;
	if (x <= mid) {
		update(ls[rt], l, mid, x, y);
	} else {
		update(rs[rt], mid + 1, r, x, y);
	}
}

int querycnt(int rt, int l, int r, int ql, int qr) {
	if (ql > qr || !rt) {
		return 0;
	}
	if (ql <= l && r <= qr) {
		return cnt[rt];
	}
	int mid = (l + r) >> 1, res = 0;
	if (ql <= mid) {
		res += querycnt(ls[rt], l, mid, ql, qr);
	}
	if (qr > mid) {
		res += querycnt(rs[rt], mid + 1, r, ql, qr);
	}
	return res;
}

ll querysum(int rt, int l, int r, int ql, int qr) {
	if (ql > qr || !rt) {
		return 0;
	}
	if (ql <= l && r <= qr) {
		return sum[rt];
	}
	int mid = (l + r) >> 1;
	ll res = 0;
	if (ql <= mid) {
		res += querysum(ls[rt], l, mid, ql, qr);
	}
	if (qr > mid) {
		res += querysum(rs[rt], mid + 1, r, ql, qr);
	}
	return res;
}

int find(int rt, int l, int r, int x) {
	if (l == r) {
		return l;
	}
	int mid = (l + r) >> 1;
	if (cnt[rs[rt]] > x) {
		return find(rs[rt], mid + 1, r, x);
	} else {
		return find(ls[rt], l, mid, x - cnt[rs[rt]]);
	}
}

void solve() {
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i) {
		scanf("%d%d", &a[i], &b[i]);
		update(rt, 0, N, a[i], b[i]);
	}
	scanf("%d", &m);
	while (m--) {
		int op, x, y;
		scanf("%d%d", &op, &x);
		if (op == 1) {
			scanf("%d", &y);
			update(rt, 0, N, a[x], -b[x]);
			a[x] = y;
			update(rt, 0, N, a[x], b[x]);
		} else if (op == 2) {
			scanf("%d", &y);
			update(rt, 0, N, a[x], y - b[x]);
			b[x] = y;
		} else {
			int t = querycnt(rt, 0, N, 0, N);
			if (t < x) {
				puts("-1");
				continue;
			}
			if (t == x) {
				printf("%lld\n", querysum(rt, 0, N, 0, N));
				continue;
			}
			int pos = find(rt, 0, N, x);
			ll p = querycnt(rt, 0, N, pos + 1, N), q = querysum(rt, 0, N, pos + 1, N);
			printf("%lld\n", q + (x - p) * pos);
		}
	}
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:rt,AtCoder,return,Beginner,Contest,int,res,mid,ql
From: https://www.cnblogs.com/zltzlt-blog/p/17456504.html

相关文章

  • AtCoder Beginner Contest 258 G Grid Card Game
    洛谷传送门AtCoder传送门记\(b_i=\sum\limits_{j=1}^ma_{i,j},c_j=\sum\limits_{i=1}^na_{i,j}\)。首先考虑这样一个事情,就是对于\(b_i\le0\)的行有没有可能被选。如果选了它:如果没有选任何列,选这一行肯定不优;如果选了若干列,根据题目的要求,这若干列与这......
  • AtCoder Regular Contest 145
    A答案为Yes当且仅当$s[1]\ne$A或$s[n]\ne$B。注意判\(n=2\)。BAlice可胜利当且仅当\(n\gea\wedgen\bmoda<b\)。C显然我们应该凑\((2i-1,2i)\)。那么我们用一个括号序列描述\(2i-1\)和\(2i\),不难发现答案为\[\frac{\binom{2n}{n}}{n+1}......
  • AtCoder Beginner Contest 304 ABCDE
    AtCoderBeginnerContest304感觉手速场,后\(80\)分钟纯纯坐牢,A-FirstPlayer一些人坐成一个环,从年龄最小开始输出名字constintN=2e5+10;intn;strings[N];inta[N];voidsolve(){intm=1e9+2,p=1;cin>>n;for(inti=1;i<=n;......
  • AtCoder Beginner Contest 304
    A-FirstPlayer(abc304a)题目大意依次给定每个人的姓名和年龄,排成一圈。从年龄最小的人依次输出姓名。解题思路找到年龄最小的,依次输出就好了。神奇的代码#include<bits/stdc++.h>usingnamespacestd;usingLL=longlong;intmain(void){ios::sync_with_......
  • Beginner:Client libraries-10 创建并使用插件
    目标:学习创建和加载一个简单的插件使用pluginlib背景本教程来自于 http://wiki.ros.org/pluginlib and WritingandUsingaSimplePluginTutorial.pluginlib是一个c++库,用于从ROS包中加载和卸载插件。插件是从运行库(即共享对象、动态链接库)加载的可动态加载类。使用plugi......
  • Beginner:Client libraries-9 使用ros2doctor识别问题
    目标:在ros2系统中通过ros2doctor工具来识别问题。背景当ros2系统没有按预期运行,可以通过ros2doctor来检查设置。ros2doctor检查ros2的所有方面,包括平台,版本,网络,环境,运行系统等等,警告你可能的错误和问题的原因。ros2doctor是ros2cli的一部分。只要ros2cli按照常规安装,就可以使......
  • Beginner:Client libraries-8 在类中使用参数
    目标:创建和运行一个具有ROS参数的类背景当实现自己节点的时候,可能需要从launch文件中添加参数。本教程的目的是告诉你怎样在c++类中创建这些参数,以及怎样在launch文件中设置。任务1、创建一个包ros2pkgcreate--build-typeament_cmakecpp_parameters--dependenciesrcl......
  • Beginner:Client libraries-7实现自定义接口
    目标:在ROS2中学习更多的实现自定义接口背景在指定的接口包中声明接口,有时在一个包中声明、创建、使用所有接口很方便。本教程关注msg接口类型,但是步骤对于其他所有接口类型适用。任务1、创建一个包ros2pkgcreate--build-typeament_cmakemore_interfacesmkdirmore_in......
  • AtCoder Beginner Contest 286(G)
    AtCoderBeginnerContest286(G)G(欧拉路径)G题意大致为\(n\)个点,\(m\)个边的图,然后给出\(k\)条边的编号,问我们这\(k\)条边可不可以在一条路径上(每条边都可以经过)对于可不可以存在一条路径,里面包含个题目所给的\(k\)条边,其实就是问是否存在一条路可以经历这\(k\)条边,然后我们......
  • Beginner:Client libraries-3 创建一个包
    目标:使用CMake或者Python来创建一个新的包,运行可执行程序;背景1、ROS2的包是什么一个包是作为ROS2代码的组织单元。如果你想安装你的代码或与他人共享,那么你需要将其组织在一个包中。有了软件包,您可以发布您的ROS2作品,并允许其他人轻松构建和使用它。在ROS2中包的创建使用amen......