atcoder Silver Fox vs Monster (贪心 一维差分)
原创
©著作权归作者所有:来自51CTO博客作者qq639708f19d17e的原创作品,请联系作者获取转载授权,否则将追究法律责任
题目大意:
现在有n个怪物,第i个怪物有血量Hi,现在我们可以使用AOE攻击,使得放AOE的中心范围内2*X长度的怪物血量减少A. 问我们最少需要多少次AOE攻击。
AOE攻击示例:
解题思路:
首先,我们想到做一些预处理,包括把每个怪物的血量理解为需要多少次攻击,然后让这些怪物按照坐标从小到大排序。这时候我们就可以贪心了,已知要处理的怪物位置为pos,而且血量大于0,那么让这只怪物承受的攻击范围是左端点,这样可以尽可能地让右边的怪物受到攻击 即: 一段攻击的距离为[pos,pos+2x ] 对于处在pos位置的需要攻击的怪物。然后我们需要用到二分查找pos+2x 的怪物,完成区间减的操作,区间减需要用到差分。
#include <bits/stdc++.h>
#define int long long
using namespace std;
int32_t main(){
int n,d,a;cin>>n>>d>>a;
vector<pair<int,int>> arrmv;
for(int i=0;i<n;i++){
int x,y;cin>>x>>y;
arrmv.push_back({x,(int)ceil((double)y/(double)a)});
}
sort(arrmv.begin(),arrmv.end());
vector<int> dif(arrmv.size()+1,0);
int ans=0;
vector<int> sha;
for(int i=0;i<(int)arrmv.size();i++)sha.push_back(arrmv[i].first);
for(int i=0;i<(int)arrmv.size();i++){
if(i)dif[i]+=dif[i-1];
arrmv[i].second+=dif[i];
if(arrmv[i].second<=0)continue;
else{
ans+=arrmv[i].second;
int lpos=upper_bound(sha.begin(),sha.end(),arrmv[i].first+2*d)-sha.begin();
dif[i]-=arrmv[i].second;
dif[lpos]+=arrmv[i].second;
}
}
cout<<ans<<endl;
return 0;
}