草庐IT

第十三届蓝桥杯省赛 C++ C 组 I 题、Python B 组 H题——技能升级(AC)

执 梗 2023-04-05 原文

目录

1.技能升级

1.题目描述

小蓝最近正在玩一款 RPG 游戏。
他的角色一共有 N N N 个可以加攻击力的技能。

其中第 i i i个技能首次升级可以提升 A i A_i Ai点攻击力,以后每次升级增加的点数都会减少 B i B_i Bi ⌈ A i B i ⌉ ⌈\frac {Ai} {Bi}⌉ BiAi(上取整)次之后,再升级该技能将不会改变攻击力。

现在小蓝可以总计升级 M M M 次技能,他可以任意选择升级的技能和次数。

请你计算小蓝最多可以提高多少点攻击力?

2.输入格式

输入第一行包含两个整数 N N N M M M
以下 N N N 行每行包含两个整数 A i A_i Ai B i B_i Bi

3.输出格式

输出一行包含一个整数表示答案。

4.样例输入

3 6
10 5
9 2
8 1

5.样例输出

47

6.数据范围

1 ≤ N ≤ 1 0 5 , 1 ≤ M ≤ 2 × 1 0 9 , 1 ≤ A i , B i ≤ 1 0 6 。 1≤N≤10^5 ,1≤M≤2×10^9,1≤Ai,Bi≤10^6。 1N1051M2×1091Ai,Bi106

7.原题链接

技能升级

2.解题思路

根据题意思考虑,每一个技能的提升点数都会是一个递减的等差序列,首项为 a i a_i ai,公差为 b i b_i bi,那么对于第 i i i 个序列应为:
a i , a i − b i , a i − 2 b i … , a i − ⌈ a i b i ⌉ b i a_i,a_i-b_i,a_i-2b_i…,a_i-⌈\frac {a_i} {b_i}⌉b_i aiaibiai2bi,aibiaibi
出于贪心考虑,我们每次将升级当前最大的 a i a_i ai,这样选够 m m m 次一定为正确答案,所以我们可以使用优先队列模拟,这样的复杂度为 O ( m l o g n ) 。 O(mlogn)。 O(mlogn) m m m 最大值为 2 × 1 0 9 2×10^9 2×109,这样会TLE

考虑完成所有选择以后,我们选择的情况一定如下图(红色表示已选),即每个技能一定在其头部选择了若干个元素,总共需要选够 m m m 个元素,因为每个数组都是递减的,所以选择的所有元素一定是所有元素的前 m m m 大的元素。那么这就是一个多路归并问题。

什么是多路归并呢,这里顾名思义就是直接将所有序列合起来,以题目样例举例:
技能1 10 10 10 5 5 5
技能2 9 9 9 7 7 7 5 5 5 3 3 3 1 1 1
技能3 8 8 8 7 7 7 6 6 6 5 5 5 4 4 4 3 3 3 2 2 2 1 1 1
我们将三个序列合并后按从大到小进行排序得到新序列 H H H:
H = [ 10 , 9 , 8 , 7 , 7 , 6 , 5 , 5 , 5 , 4 , 3 , 3 , 2 , 1 , 1 ] H=[10,9,8,7,7,6,5,5,5,4,3,3,2,1,1] H=[10,9,8,7,7,6,5,5,5,4,3,3,2,1,1]

样例的 m m m6,那么答案即为最大前6个元素之和,这就是多路归并的思想,由贪心可知这样的选择一定正确且我们可以通过在题目的要求下完成如此选法。但显然我们如果暴力存储然后排序仍会TLE,考虑如何去进行优化。

首先思考多路归并的数组对我们有什么作用?答案是我们可以求解得到我们选择的第 m m m 个数是多少,定义 f ( x ) f(x) f(x) 为所有数列中大于等于 x x x 的数有多少个。

f ( x ) f(x) f(x)的定义可知,若某个值 t t t 满足 f ( t ) = m f(t)=m f(t)=m,那么数列中所有大于等于 t t t 的数恰好就是前 m m m 大的数。又可知当 x < y x<y x<y时,一定满足 f ( x ) ≥ f ( y ) f(x)≥f(y) f(x)f(y),所以当 x x x 满足 f ( x ) ≥ m f(x)≥m f(x)m时, x − 1 x-1 x1也一定满足,而 x + 1 x+1 x+1却不一定满足,由此符合二段性,所以我们可以去二分求解得到 t t t,其实就是求满足 f ( x ) ≥ m f(x)≥m f(x)m 的最大值。

比如样例中二分求得的 t t t 就是 6,因为 f ( 6 ) = m f(6)=m f(6)=m,那么我们把所有大于等于6的数都选上即是答案。

但是已知 x x x,如何求得 f ( x ) f(x) f(x)?对于第 i i i 个数列,我们可以选择的个数为 ( a i − x ) / b i + 1 (a_i-x)/b_i+1 (aix)/bi+1,那么对于任意一个 x x x 我们都可以在 O ( n ) O(n) O(n)的时间复杂度求得 f ( x ) f(x) f(x)。加上我们二分的复杂度为 O ( l o g n ) O(logn) O(logn),那么我们可以在 O ( n l o g n ) O(nlogn) O(nlogn)的复杂度求解得到 t t t

得到 t t t 之后就简单了,我们只需要把每个数列中大于等于 t t t 的值都选上即可。这也很好求解,由于是等差数列,那么每个数组可选的个数为 ( a i − t ) / b i + 1 (a_i-t)/b_i+1 (ait)/bi+1,首项为 a i a_i ai,那么末项为 a i − ( c − 1 ) ∗ b i a_i-(c-1)*b_i ai(c1)bi,已知首项末项以及项数,根据等差数列求和公式 S = n 2 ( a 1 + a n ) S=\frac {n}{2}(a_1+a_n) S=2n(a1+an)可以求出每一列我们选的总和。

需要注意的是,我们求解的 t t t 是满足 f ( t ) > = m f(t)>=m f(t)>=m并不一定恰好是 f ( t ) = m f(t)=m f(t)=m,因为原数列中可能有多个 t t t,我们可能会选多,所以还需要记录下我们总共选了多少个数,最后减去多余的 t t t。比如如果样例中存在两个6,那么我们就会选到7个数,需要减去一个6
时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)

3.Ac_code

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
#define pb(s) push_back(s);
#define SZ(s) ((int)s.size());
#define ms(s,x) memset(s, x, sizeof(s))
#define all(s) s.begin(),s.end()
const int inf = 0x3f3f3f3f;
const int mod = 1000000007;
const int N = 200010;

LL n, m;
void solve()
{
	cin >> n >> m;
	std::vector<LL> a(n), b(n);
	for (int i = 0; i < n; ++i) cin >> a[i] >> b[i];
	auto check = [&](int x) {
		LL s = 0;
		for (int i = 0; i < n; ++i) {
			if (a[i] >= x) s += (a[i] - x) / b[i] + 1;
		}
		return s >= m;
	};
	int l = 0, r = 1e6;
	while (l < r) {
		int mid = l + r + 1 >> 1;
		if (check(mid)) l = mid;
		else r = mid - 1;
	}
	LL ans = 0, cnt = 0;
	for (int i = 0; i < n; ++i) {
		if (a[i] >= r) {
			//可取个数
			LL c = (a[i] - r) / b[i] + 1;
			//末项
			LL end = a[i] - (c - 1) * b[i];
			//求和
			ans += (a[i] + end) * c / 2;
			cnt += c;
		}
	}
	ans -= (cnt - m) * r;
	cout << ans << '\n';
}
int main()
{
	ios_base :: sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	int t = 1;
	while (t--)
	{
		solve();
	}
	return 0;
}

有关第十三届蓝桥杯省赛 C++ C 组 I 题、Python B 组 H题——技能升级(AC)的更多相关文章

  1. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  2. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  3. ruby - 如何在 Lion 上安装 Xcode 4.6,需要用 RVM 升级 ruby - 2

    我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121

  4. ruby - 在不使用 RVM 的情况下在 Mac 上卸载和升级 Ruby - 2

    我最近决定从我的系统中卸载RVM。在thispage提出的一些论点说服我:实际上,我的决定是,我根本不想担心Ruby的多个版本。我只想使用1.9.2-p290版本而不用担心其他任何事情。但是,当我在我的Mac上运行ruby--version时,它告诉我我的版本是1.8.7。我四处寻找如何简单地从我的Mac上卸载这个Ruby,但奇怪的是我没有找到任何东西。似乎唯一想卸载Ruby的人运行linux,而使用Mac的每个人都推荐RVM。如何从我的Mac上卸载Ruby1.8.7?我想升级到1.9.2-p290版本,并且我希望我的系统上只有一个版本。 最佳答案

  5. 神州数码无线产品(AC+AP)配置 - 2

    注意:本文主要掌握DCN自研无线产品的基本配置方法和注意事项,能够进行一般的项目实施、调试与运维AP基本配置命令AP登录用户名和密码均为:adminAP默认IP地址为:192.168.1.10AP默认情况下DHCP开启AP静态地址配置:setmanagementstatic-ip192.168.10.1AP开启/关闭DHCP功能:setmanagementdhcp-statusup/downAP设置默认网关:setstatic-ip-routegeteway192.168.10.254查看AP基本信息:getsystemgetmanagementgetmanaged-apgetrouteAP配

  6. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  7. ruby-on-rails - 从 Rails 2.3 升级到 Rails 4.0 - 2

    我们有一个目前在Rails2.3.12版和Ruby1.8.7版上运行的应用程序。我们想将我们的应用程序更新到Rails4.0和Ruby2.1.0。我们有大约200个模型和150个Controller。我想知道升级过程需要多大的努力。您还可以提供升级可以遵循的步骤。我们应该先升级Ruby然后再升级Rails还是相反? 最佳答案 您想要实现的目标将是史诗般的努力。我无法为您提供分步说明,因为不可能在一个答案中涵盖所有情况。我建议不要同时升级Ruby和Rails,而是分步升级。升级本身的复杂性是巨大的,但只要您的应用程序具有合理的测试覆盖

  8. ruby - 如何保持我不常用的编程语言技能 - 2

    关闭。这个问题是off-topic.它目前不接受答案。想改进这个问题吗?Updatethequestion所以它是on-topic用于堆栈溢出。关闭11年前。Improvethisquestion我不经常使用ruby​​-通常它加起来相当于每两个月或更长时间编写一次脚本。我的大部分编程都是使用C++进行的,这与ruby​​有很大不同。由于我与ruby​​之间的差距如此之大,我总是忘记语言的基本方面(比如解析文本文件和其他简单的东西)。我想每天练习一些基本的东西,我想知道是否有一些我可以订阅的网站,并且会向我发送当天的Ruby问题或类似的东西。有人知道这样的站点/Internet服务吗?

  9. 玩以太坊链上项目的必备技能(初识智能合约语言-Solidity之旅一) - 2

    前面一篇关于智能合约翻译文讲到了,是一种计算机程序,既然是程序,那就可以使用程序语言去编写智能合约了。而若想玩区块链上的项目,大部分区块链项目都是开源的,能看得懂智能合约代码,或找出其中的漏洞,那么,学习Solidity这门高级的智能合约语言是有必要的,当然,这都得在公链``````以太坊上,毕竟国内的联盟链有些是不兼容Solidity。Solidity是一种面向对象的高级语言,用于实现智能合约。智能合约是管理以太坊状态下的账户行为的程序。Solidity是运行在以太坊(Ethereum)虚拟机(EVM)上,其语法受到了c++、python、javascript影响。Solidity是静态类型

  10. 蓝桥杯备赛(二) - 2

    目录前言: 一、ASC分析代码实现二、 卡片分析代码实现三、 直线分析代码实现四、货物摆放分析代码实现小结:前言:  在刷题的过程中,发现蓝桥杯的题目和力扣的差别很大。让人有一种不一样的感觉,蓝桥杯题目偏向对于实际问题用编程去的解决,而力扣给人感觉很锻炼自己的编程思维,逻辑能力。两者结合去刷,相信会有不一样的收获。 一、ASC  已知大写字母A的ASCII码为65,请问大写字母L的ASCII码是多少?分析  这道题目看上去很简单,我们需确定自己计算的准确,所以我建议用编程去解决。代码实现publicclassTest8{publicstaticvoidmain(String[]args){Sy

随机推荐