1. 程式人生 > >【Codeforces Round #456 (Div. 2) C】Perun, Ult!

【Codeforces Round #456 (Div. 2) C】Perun, Ult!

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!