Educational Codeforces Round 168 (Rated for Div. 2) E.Level Up
E.Level UP
二分答案 + 树状数组
单调性:因为
越小,怪兽越是容易逃跑
对每个怪物,二分答案出与之战斗的最小
树状数组用于记录在当前位置之前,在不同的
从前往后遍历,每个位置的阙值为下标,这样
pt.get(x)
就能得到在参数为 时,前面能与多少怪物战斗
- 因为
越大,怪物越容易与其战斗,所以在参数为 的情况下,树状数组前面那些阙值小的敌人自然也会战斗 - 每个位置的敌人都会执行
pt.add(x, 1)
,记录有一个敌人的阙值为
#define int long long//记得开long long
//树状数组模板
template<class T> struct BIT {
int n;
vector<T> w;
BIT(int n) : n(n), w(n + 1) {}
BIT(int n, vector<T> &in) : n(n), w(n + 1) {
for(int i = 1; i <= n; i++) {
add(i, in[i]);
}
}
void add(int x, T v) {
for(; x <= n; x += (x & -x)) {
w[x] += v;
}
}
T get(int x) {
T ans = 0;
for(; x; x -= (x & -x)) {
ans += w[x];
}
return ans;
}
T get(int l, int r) {
return get(r) - get(l - 1);
}
};
void solve(int cas) {
int n, q; cin >> n >> q;
vector<int> a(n + 1), req(n + 1);
BIT<int> pt(n);
for(int i = 1; i <= n; i++) cin >> a[i];
//检查在k为x时,idx处的怪物是否战斗,如果战斗则返回true,逃跑返回false
auto check = [&](int idx, int x) {
//pt.get(x)表示在参数k为x的情况下,前面发生战斗的怪物数量
//a[idx] * x表示要升级到a[idx] + 1级需要战斗a[idx] * x只怪
//如果实际能战斗的怪物数pt.get(x)比 a[idx] * x少,那战斗完等级就低于或等于怪物等级,此时会战斗,否则等级高于怪物等级,怪物会逃跑
return a[idx] * x > pt.get(x);
};
for(int i = 1; i <= n; i++) {
//二分找出与使怪物战斗的最小k值
int l = 1, r = n;
while(l < r) {
int mid = l + r >> 1;
if(check(i, mid)) r = mid;
else l = mid + 1;
}
//将树状数组中的l处+1
pt.add(l, 1);
//req记录:能与第i的怪物战斗的最小k值为l
req[i] = l;
}
while(q--) {
int idx, k; cin >> idx >> k;
//如果比阙值还小,说明等级大于怪物等级,怪物会逃跑
if(k < req[idx]) cout << "NO" << endl;
else cout << "YES" << endl;
}
}
分类:
算法题解
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 本地部署 DeepSeek:小白也能轻松搞定!
· 如何给本地部署的DeepSeek投喂数据,让他更懂你
· 基于DeepSeek R1 满血版大模型的个人知识库,回答都源自对你专属文件的深度学习。
· 在缓慢中沉淀,在挑战中重生!2024个人总结!
· 大人,时代变了! 赶快把自有业务的本地AI“模型”训练起来!