洛谷 P8365 [LNOI2022] 吃

P8365 [LNOI2022] 吃

题目描述

小 A 很喜欢吃东西。

小 A 面前有 n 份食物,第 i 份有参数 ai 和 bi​。小 A 可以按照任意顺序吃掉这 nn 份食物。当她吃掉编号为 ii 的食物时,她可以选择将自己的体重乘以 a_iai​ 或者将自己的体重加上 b_ibi​。每份食物只能吃恰好一次。

小 A 的初始体重为 1,请求出她吃完 n 份食物后能达到的最大体重。答案可能很大,你只需要输出其对 (10^9 +7) 取模后的结果。

注意:你需要最大化体重并将该最大值对 (10^9 + 7)(10^9+7) 取模,而非最大化体重对 \bm{({10}^9 + 7)}(109+7) 取模的结果。


输入格式

第一行输入一个整数 n 表示食物的数量。第二行 n 个整数 a1, a2, ......,an​,第三行 n 个整数 b1, b2​,...…,bn​,表示每份食物的参数。

输出格式

输出一个整数,表示小 A 可以得到的最大体重对 (10^9 + 7) 取模后的结果。

输入输出样例

输入 #1

5
1 2 3 4 5
100 200 300 400 500

输出 #1

18060

说明/提示

【样例解释 #1】

以下方案可以达到最大体重:

  • 吃掉第一份食物并选择将体重增加 100100,体重变为 101101;
  • 吃掉第二份食物并选择将体重增加 200200,体重变为 301301;
  • 吃掉第三份食物并选择将体重乘 33,体重变为 903903;
  • 吃掉第四份食物并选择将体重乘 44,体重变为 36123612;
  • 吃掉第五份食物并选择将体重乘 55,体重变为 1806018060。

【样例 #2】

见附件中的 food/food2.in 与 food/food2.ans

该组样例满足 n \le 10n≤10 和特殊性质 E。

【样例 #3】

见附件中的 food/food3.in 与 food/food3.ans

该组样例满足 n \le 20n≤20 和特殊性质 E。

【样例 #4】

见附件中的 food/food4.in 与 food/food4.ans

该组样例满足 n \le 2000n≤2000。

【样例 #5】

见附件中的 food/food5.in 与 food/food5.ans

该组样例满足特殊性质 A。

【样例 #6】

见附件中的 food/food6.in 与 food/food6.ans

该组样例满足特殊性质 C。

【样例 #7】

见附件中的 food/food7.in 与 food/food7.ans

该组样例满足特殊性质 D。

【样例 #8】

见附件中的 food/food8.in 与 food/food8.ans

该组样例满足特殊性质 B。

【样例 #9】

见附件中的 food/food9.in 与 food/food9.ans

【数据范围】

对于 100 \%100% 的测试数据,1 \le n \le 5 \times {10}^51≤n≤5×105,1 \le a_i, b_i \le {10}^61≤ai​,bi​≤106。

测试点编号n \len≤特殊性质
110DE
210E
310AE
410E
520DE
620E
720E
820E
92000D
102000
112000
122000
135 ×10^5BD
145 ×10^5B
155 ×10^5C
165 ×10^5C
1710^5
1810^5
195 ×10^5
205 ×10^5

特殊性质 A:ai = 1。
特殊性质 B:ai  \geq bi​。
特殊性质 C:ai, b_i​ 在 [1, {10}^6] 内独立均匀随机生成。
特殊性质 D:ai \geq 2。
特殊性质 E:ai \le 4。

 

附件下载

  food.zip 12.01MB

答案(博主自己做的,如有不善,谢谢改正)

#include <iostream>
#include <cstdio>
#include <climits>//need "INT_MAX","INT_MIN"
#include <cstring>//need "memset"
#include <numeric>
#include <algorithm>
#include <cmath>
#define int long long
#define enter putchar(10)
#define debug(c,que) std::cerr << #c << " = " << c << que
#define cek(c) puts(c)
#define blow(arr,st,ed,w) for(register int i = (st);i <= (ed); ++ i) std::cout << arr[i] << w;
#define speed_up() std::ios::sync_with_stdio(false),std::cin.tie(0),std::cout.tie(0)
#define mst(a,k) memset(a,k,sizeof(a))
#define stop return(0)
const int mod = 1e9 + 7;
inline int MOD(int x) {
	if(x < 0) x += mod;
	return x % mod;
}
namespace Newstd {
	inline int read() {
		int ret = 0,f = 0;char ch = getchar();
		while (!isdigit(ch)) {
			if(ch == '-') f = 1;
			ch = getchar();
		}
		while (isdigit(ch)) {
			ret = (ret << 3) + (ret << 1) + ch - 48;
			ch = getchar();
		}
		return f ? -ret : ret;
	}
	inline double double_read() {
		long long ret = 0,w = 1,aft = 0,dot = 0,num = 0;
		char ch = getchar();
		while (!isdigit(ch)) {
			if (ch == '-') w = -1;
			ch = getchar();
		}
		while (isdigit(ch) || ch == '.') {
			if (ch == '.') {
				dot = 1;
			} else if (dot == 0) {
				ret = (ret << 3) + (ret << 1) + ch - 48;
			} else {
				aft = (aft << 3) + (aft << 1) + ch - '0';
				num ++;
			}
			ch = getchar();
		}
		return (pow(0.1,num) * aft + ret) * w;
	}
	inline void write(int x) {
		if(x < 0) {
			putchar('-');
			x = -x;
		}
		if(x > 9) write(x / 10);
		putchar(x % 10 + '0');
	}
}
using namespace Newstd;

const int N = 5e5 + 5;
struct Node {
	int mul,add;
	bool used;
} node[N];
int n;
#undef int
int main(void) {
	#define int long long
	n = read();
	for (register int i = 1;i <= n; ++ i) node[i].mul = read();
	for (register int i = 1;i <= n; ++ i) node[i].add = read();
	int ans = 1;
	for (register int i = 1;i <= n; ++ i) {
		if (node[i].mul == 1) {
			ans = ans + node[i].add;
			node[i].used = true;
		}
	}
	long double Max = ans;
	int pos = -1;
	for (register int i = 1;i <= n; ++ i) {
		if (!node[i].used) {
			long double p = (long double)(ans + node[i].add) / (long double)node[i].mul;
			if (p > Max) {
				Max = p;
				pos = i;
			}
		}
	}
	int res = ans;
	if (pos == -1) {
		for (register int i = 1;i <= n; ++ i) {
			if (!node[i].used) {
				res = res * node[i].mul % mod;
			}
		}
	} else {
		res = res + node[pos].add;
		for (register int i = 1;i <= n; ++ i) {
			if (!node[i].used && i != pos) {
				res = res * node[i].mul % mod;
			}
		}
	}
	printf("%lld\n",res);
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值