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

【Codeforces】CF 1997 E

Level Up

#数据结构 #二分 #树状数组

题目描述

Monocarp is playing a computer game. He starts the game being level 1 1 1. He is about to fight n n n monsters, in order from 1 1 1 to n n n. The level of the i i i-th monster is a i a_i ai.

For each monster in the given order, Monocarp’s encounter goes as follows:

  • if Monocarp’s level is strictly higher than the monster’s level, the monster flees (runs away);
  • otherwise, Monocarp fights the monster.

After every k k k-th fight with a monster (fleeing monsters do not count), Monocarp’s level increases by 1 1 1. So, his level becomes 2 2 2 after k k k monsters he fights, 3 3 3 after 2 k 2k 2k monsters, 4 4 4 after 3 k 3k 3k monsters, and so on.

You need to process q q q queries of the following form:

  • i   x i~x i x: will Monocarp fight the i i i-th monster (or will this monster flee) if the parameter k k k is equal to x x x?

输入格式

The first line contains two integers n n n and q q q ( 1 ≤ n , q ≤ 2 ⋅ 1 0 5 1 \le n, q \le 2 \cdot 10^5 1n,q2105) — the number of monsters and the number of queries. The second line contains n n n integers a 1 , a 2 , … , a n a_1, a_2, \dots, a_n a1,a2,,an ( 1 ≤ a i ≤ 2 ⋅ 1 0 5 1 \le a_i \le 2 \cdot 10^5 1ai2105) — the levels of the monsters. In the j j j-th of the following q q q lines, two integers i i i and x x x ( 1 ≤ i , x ≤ n 1 \le i, x \le n 1i,xn) — the index of the monster and the number of fights required for a level up in the j j j-th query.

输出格式

For each query, output “YES”, if Monocarp will fight the i i i-th monster in this query, and “NO”, if the i i i-th monster flees.

样例 #1

样例输入 #1

4 16
2 1 2 1
1 1
2 1
3 1
4 1
1 2
2 2
3 2
4 2
1 3
2 3
3 3
4 3
1 4
2 4
3 4
4 4

样例输出 #1

YES
NO
YES
NO
YES
YES
YES
NO
YES
YES
YES
NO
YES
YES
YES
YES

解法

解题思路

首先我们发现,对于位置 i i i的怪物,能够与它战斗的 k k k一定满足单调性,也就是 k k k越大,就越有可能与它发生战斗,相应的,我们可以得到一个阈值,在这个值之前一定不会战斗,在这个值之后,一定会战斗,我们考虑如何求这个阈值。

因为位置在 i i i怪物之前的怪物可能会发生战斗,从而提升我们的等级,因此,我们需要考虑什么样的怪物对我们的等级会有贡献。

容易发现,如果我们当前可以与怪兽发生战斗的最低等级为 k k k,那么就会对 k − I N F k-INF kINF的升级轮数具有贡献经验的作用。

因此我们可以从左到右枚举每个怪物 ,然后二分出我们可以与它战斗的最低等级。二分时,我们只需要判断当前的经验能让我们升多少级,并与怪物的等级作比较,最后我们再使用树状数组将 k − I N F k-INF kINF的升级轮数加上 1 1 1即可。

在预处理之后,就可以进行 O ( 1 ) O(1) O(1)查询啦

代码


const int N = 2e5 + 10;
 
int tree[N];
 
int n, q;
inline int lowbit(int x) { return x & (-x); }
inline void add(int i, int val) {
	while (i <= n) {
		tree[i] += val;
		i += lowbit(i);
	}
}
 
inline int query(int i) {
	int res = 0;
	while (i > 0) {
		res += tree[i];
		i -= lowbit(i);
	}
	return res;
}
 
void solve() {
	std::cin >> n >> q;
 
	std::vector<int>a(n + 1);
	for (int i = 1; i <= n; ++i) {
		std::cin >> a[i];
	}
 
	std::vector<int>res(n + 1);
	for (int i = 1; i <= n; ++i) {
		int l = 1, r = n, k = 1;
		while (l <= r) {
			int mid = l + r >> 1;
			int s = query(mid) / mid + 1;
			if (s <= a[i]) {
				k = mid;
				r = mid - 1;
			}
			else {
				l = mid + 1;
			}
		}
		res[i] = k;
		add(k, 1);
	}
 
	while (q--) {
		int i, x;
		std::cin >> i >> x;
 
		if (x >= res[i]) std::cout << "YES\n";
		else std::cout << "NO\n";
	}
}
 
signed main() {
	std::ios::sync_with_stdio(0);
	std::cin.tie(0);
	std::cout.tie(0);
 
	int t = 1;
	//std::cin >> t;
 
	while (t--) {
		solve();
	}
};

http://www.kler.cn/news/337447.html

相关文章:

  • 刷题 图论
  • leetcode_238:除自身以外数组的乘积
  • 【探索艺术新纪元:Midjourney中文版,让创意无界!】
  • vscode配置golang
  • LVM——让Linux磁盘空间的弹性管理
  • 计算机网络:计算机网络概述 —— 描述计算机网络的参数
  • 【2024保研经验帖】中山大学生物医学工程7月份夏令营
  • VS对Qt实现控件提升,并解决头文件Include方式不正确的问题
  • ThinkBook 16+ 锐龙6800h 安装ubuntu键盘失灵
  • 下标记数(一)
  • PostgreSQL 任意命令执行漏洞(CVE-2019-9193)
  • 嵌入式硬件设计
  • 解锁手机截屏新姿势,五大技巧让你成为屏幕捕手
  • C语言期中自测试卷
  • 云原生(四十九) | WordPress源码部署
  • 自动驾驶系列—揭秘毫米波雷达:自动驾驶的眼睛如何看穿复杂环境?
  • 深度学习:基于MindSpore实现ResNet50中药分拣
  • 【无人机设计与技术】基于EKF的四旋翼无人机姿态估计matlab仿真
  • 【实战教程】SpringBoot全面指南:快速上手到项目实战(SpringBoot)
  • 【大数据应用开发】2023年全国职业院校技能大赛赛题第02套