【Codeforces Round #456 (Div. 2) C】Perun, Ult!
阿新 • • 發佈:2018-01-06
set != bound names begin pre round 部分 之前
【鏈接】 我是鏈接,點我呀:)
【題意】
在這裏輸入題意
【題解】
set1 < pair < int,int > > set1;記錄關鍵點->某個人怪物永遠打不死了,第一維是時間,第二維是下標
int dic[1e5+10] //記錄對應下標的怪物它此時此刻在何時打不死了 set2 < pair< int,int > > set2;關鍵點2->有怪物要更新了的時間點,以及記錄的信息下標idx2 之所以這樣記錄。是為了盡可能多地讓怪物存活時間長一點 if (start > damage) continue;else
//special表示這個怪物一直能被打死。
//delta表示目前為止一直能被打死的怪物的個數
if (max_h <= damage ||(start<=damage && rec==0)) {delta++; special[i] = 1;continue;}else{
int time = damage-start/rec;->取整數部分就可以了
set1.insert(time,idx);
dic[idx] = time;
}
set2.insert(timej,j); set1和set2裏面找關鍵點。 先找小的時間mi 如果是set1的話 temp = set1.size(); if (上一個時間和這個時間相同) temp = 上一次set1的size() ans = max(ans,(temp+delta)*(chushi+mi*increase)); 然後刪掉set1.begin(); 如果是set2的話 因為可能經過這次更新之後某些怪物的曲線變了。 則在變之前先嘗試更新一下答案。 時間是t2-1 num = (ll)set1.size(); ans = max(ans,(num+delta)*(bounty+(t2-1)*increase)); int idx = enemy[set2.begin().second]; pair<dic[idx],idx>; 從set1中刪掉這個東西->如果有 if (special[idx]==1) delta--; if (health>damage) continue; if (maxh<=damage ||(updateheadl<=damage && rec==0)) {delta++;special[idx] = 1;continue;else{ int time = (damage-update)/rec set1.insert(timebegin+time,idx) } 最後統計special的個數cnt
如果cnt>0且increase!=0 那麽輸出無限大
否則increase==0 則 再用cnt*bounty和ans比一下取較大值;->防止沒有更新操作的時候一次ans都沒有取到
【代碼】
#include <bits/stdc++.h>
#define ll long long
#define time mytime
using namespace std;
const int N = 1e5;
set<pair<ll,int> > set1,set2;
int n,m;
ll bounty,increase,damage;
ll max_h[N+10 ],start_h[N+10],regen[N+10];
ll time[N+10],enemy[N+10],health[N+10],dic[N+10],delta = 0;
bool special[N+10];
int main(){
#ifdef LOCAL_DEFINE
freopen("rush_in.txt", "r", stdin);
#endif
ios::sync_with_stdio(0),cin.tie(0);
memset(dic,255,sizeof dic);
cin >> n >> m;
cin >> bounty >> increase >> damage;
for (int i = 1;i <= n;i++){
cin >> max_h[i] >> start_h[i] >> regen[i];
if (start_h[i]>damage) continue;
if (max_h[i]<=damage ||(start_h[i]<=damage && regen[i]==0)){
special[i] = 1;
delta++;
continue;
}
ll time = (damage-start_h[i])/regen[i];
dic[i] = time;
set1.insert({time,i});
}
for (int i = 1;i <= m;i++){
cin >> time[i] >> enemy[i] >> health[i];
set2.insert({time[i],i});
}
ll ans = 0;
int pre = -1;
ll prenum = 0;
while (!set1.empty() || !set2.empty()){
ll t1 = -1,t2 = -1;
if (!set1.empty()) t1 = (*set1.begin()).first;
if (!set2.empty()) t2 = (*set2.begin()).first;
//等於的話先處理更新的
if (t1!=-1 &&(t2==-1 || t1 <t2)){
ll time2 = (*set1.begin()).first;
ll num = (ll)set1.size();
if (pre!=-1 && time2==pre){
num = prenum;
}else {
pre = time2;
prenum = num;
}
ans = max(ans,(num+delta)*(bounty+t1*increase));
set1.erase(set1.begin());
}else{
ll num = (ll)set1.size();
ans = max(ans,(num+delta)*(bounty+(t2-1)*increase));
int tempidx = (*set2.begin()).second;
set2.erase(set2.begin());
int idx =enemy[tempidx];
auto it = set1.upper_bound({dic[idx],idx});
if (it!=set1.begin()){
it--;
pair<ll,int> temp = (*it);
if (temp.first==dic[idx] && temp.second==idx){
set1.erase(it);
}
}
if (special[idx]) delta--;
special[idx] = 0;
dic[idx] = -1;
if (health[tempidx]>damage) continue;
if (max_h[idx]<=damage ||(health[tempidx]<=damage && regen[idx]==0)){
special[idx] = 1;
delta++;
continue;
} else{
ll time1 = (damage-health[tempidx])/regen[idx];
dic[idx] = time[tempidx] + time1;
set1.insert({dic[idx],idx});
}
}
}
int cc =0;
for (int i = 1;i <= n;i++)
if (special[i])
cc++;
if (cc>0 && increase>0)
return cout<<-1,0;
else ans = max(ans,(ll)cc*bounty);
cout << ans << endl;
return 0;
}
【Codeforces Round #456 (Div. 2) C】Perun, Ult!