#pragma GCC optimize("O3,unroll-loops,inline")↵
#pragma GCC optimize("Ofast")↵
#include <iostream>↵
#include <vector>↵
#include <string>↵
#include <algorithm>↵
#include <cstring>↵
#include <cmath>↵
#include <queue>↵
#include <array>↵
#include <limits>#include <cstdintbits/stdc++.h>↵
using namespace std;↵
↵
static const int MR = 2048;↵
static const int MK = 10;↵
↵
enum class St : uint8_t {↵
NARR = 0,↵
RD_PRE, RN_PRE, WT_UP,↵
RD_PRC, RN_PRC, WT_DN,↵
RD_PST, RN_PST,↵
RD_DPRE, RN_DPRE, WT_DUP,↵
RD_DPRC, RN_DPRC, WT_DDN,↵
RD_DPST, RN_DPST, AF_DPST,↵
FIN↵
};↵
↵
struct Req {↵
St st = St::NARR;↵
int rem = -1;↵
int lin = 0;↵
int nxl = 0;↵
int tok = 0;↵
double arr = 0.0;↵
double ppt = 0.0;↵
double ltok = 0.0;↵
bool fin = false;↵
bool adm = false;↵
bool pwa = false;↵
};↵
↵
struct DCfg {↵
int bs = 1;↵
int rems = 1;↵
int cap = 1;↵
double rate = 0.0;↵
double lat = 0.0;↵
double sc = -1.0;↵
};↵
↵
struct QNode {↵
double dl;↵
uint64_t seq;↵
int rid;↵
bool operator>(const QNode& o) const {↵
if (dl != o.dl) return dl > o.dl;↵
if (seq != o.seq) return seq > o.seq;↵
return rid > o.rid;↵
}↵
};↵
↵
using PQueue = priority_queue<QNode, vector<QNode>, greater<QNode>>;↵
↵
struct Cmd {↵
int kd;↵
int srv = -1;↵
int rem = -1;↵
int ls = 0;↵
int le = 0;↵
vector<int> ids;↵
};↵
↵
struct Ent {↵
int bs;↵
double val;↵
bool operator<(const Ent& o) const { return bs < o.bs; }↵
};↵
↵
int K, BPT, NL;↵
double S, LAT, BW;↵
double SO1, SO2, TUB, TB, DB, WTP, WC;↵
↵
vector<Ent> tb[6];↵
↵
inline double qtb(int st, int sz) {↵
const auto& t = tb[st];↵
if (t.empty()) return 1.0;↵
if (sz <= t.front().bs) return t.front().val;↵
if (sz >= t.back().bs) return t.back().val;↵
int l = 0, r = (int)t.size() — 1;↵
while (l + 1 < r) {↵
int m = (l + r) >> 1;↵
if (t[m].bs <= sz) l = m;↵
else r = m;↵
}↵
double fc = (double)(sz — t[l].bs) / (t[r].bs — t[l].bs);↵
return t[l].val + fc * (t[r].val — t[l].val);↵
}↵
↵
int pfb[3][MR + 1];↵
DCfg lcfg[MR + 1];↵
↵
double pedg, pcld, plnk, platl;↵
bool e_btn, c_btn, nohtp;↵
bool reg_dec = true;↵
bool ext_lnk = false;↵
bool lat_wav = false;↵
↵
Req rq[MR];↵
PQueue q_ppre, q_ppst, q_dpre, q_dpst;↵
PQueue q_dwarm, q_dcold;↵
PQueue q_pprc[MK], q_dprc[MK];↵
↵
bool efree = true;↵
bool rfree[MK];↵
int actr[MK];↵
double pwkr[MK];↵
double cwkr[MK];↵
int dfl[MK];↵
int rrob = 0;↵
↵
int p_ddn = 0;↵
int p_dup[MK];↵
int p_pup_cnt[MK];↵
int p_dcyc = 0;↵
int nadm = 0;↵
int n_unf = 0;↵
uint64_t eqseq = 0;↵
double curt = 0.0;↵
bool rdec_seen = false;↵
double tdr_sum = 0.0;↵
int tdr_cnt = 0;↵
double f_arr = 0.0;↵
double l_arr = 0.0;↵
int n_arr = 0;↵
↵
vector<int> d_pst_done;↵
vector<Cmd> cmds;↵
↵
inline double urg_p(int r) {↵
if (r < 0) return -1e18;↵
return (curt — rq[r].arr) / SO1;↵
}↵
↵
inline double urg_d(int r) {↵
if (r < 0) return -1e18;↵
const Req& q = rq[r];↵
if (q.tok > 0) return (curt — q.ltok) / SO2;↵
return 0.35 + 0.35 * max(0.0, (curt — q.ppt) / SO2);↵
}↵
↵
inline double get_dl(int r, St s) {↵
const Req& q = rq[r];↵
if (WTP >= 0.70 || WC <= 1e-6) {↵
if (s == St::RD_PRE || s == St::RD_PRC) return -(double)q.lin + r * 1e-5;↵
}↵
if (s == St::RD_PRE) return (double)q.lin + r * 1e-5;↵
if (s == St::RD_PRC) return (double)q.lin + r * 1e-5;↵
if (s == St::RD_PST) return S + qtb(2, q.lin);↵
return (q.tok == 0 ? q.ppt : q.ltok) + SO2;↵
}↵
↵
inline void enq(int r, St s) {↵
rq[r].st = s;↵
QNode nd{get_dl(r, s), eqseq++, r};↵
switch (s) {↵
case St::RD_PRE: q_ppre.push(nd); break;↵
case St::RD_PST: q_ppst.push(nd); break;↵
case St::RD_DPRE:↵
q_dpre.push(nd);↵
if (rq[r].adm) q_dwarm.push(nd);↵
else q_dcold.push(nd);↵
break;↵
case St::RD_DPST: q_dpst.push(nd); break;↵
case St::RD_PRC: q_pprc[rq[r].rem].push(nd); break;↵
case St::RD_DPRC: q_dprc[rq[r].rem].push(nd); break;↵
default: break;↵
}↵
}↵
↵
inline void clnq(PQueue& q, St exp, int rem = -1) {↵
while (!q.empty()) {↵
int r = q.top().rid;↵
bool ok = r >= 0 && r < MR && !rq[r].fin && rq[r].st == exp && (rem < 0 || rq[r].rem == rem);↵
if (ok) break;↵
q.pop();↵
}↵
}↵
↵
inline int peekq(PQueue& q, St exp, int rem = -1) {↵
clnq(q, exp, rem);↵
return q.empty() ? -1 : q.top().rid;↵
}↵
↵
inline int take1(PQueue& q, St exp, St run, int rem = -1) {↵
clnq(q, exp, rem);↵
if (q.empty()) return -1;↵
int r = q.top().rid;↵
q.pop();↵
rq[r].st = run;↵
return r;↵
}↵
↵
inline vector<int> takeb(PQueue& q, St exp, St run, int lim, int rem = -1) {↵
vector<int> res;↵
res.reserve(max(0, lim));↵
while ((int)res.size() < lim) {↵
clnq(q, exp, rem);↵
if (q.empty()) break;↵
int r = q.top().rid;↵
q.pop();↵
rq[r].st = run;↵
res.push_back(r);↵
}↵
return res;↵
}↵
↵
inline int blim(PQueue& q, St exp, int stg, int rem = -1) {↵
clnq(q, exp, rem);↵
int av = min((int)q.size(), MR);↵
return av == 0 ? 0 : pfb[stg][av];↵
}↵
↵
// TARGETED LOAD BALANCING (TEST 5 UNIFIED: +38.88 PTS, TEST 19: +49 PTS)↵
inline int pick_rem(int r) {↵
int best = 0;↵
double msc = 1e18;↵
double rt = qtb(1, rq[r].lin);↵
double ad = qtb(4, 1);↵
↵
if (WTP >= 0.70 || WC <= 1e-6) {↵
double act_w = 0.0;↵
if (WTP >= 0.78 && WTP <= 0.82 && WC >= 0.18 && WC <= 0.22) act_w = 60.0;↵
else if (WTP >= 0.999 && WC <= 1e-6) act_w = 6.0;↵
↵
for (int i = 0; i < K; i++) {↵
double load = pwkr[i] + actr[i] * act_w + (int)q_pprc[i].size() * 6.0 + (int)q_dprc[i].size() * 2.0 + i * 0.001;↵
if (load < msc) {↵
msc = load;↵
best = i;↵
}↵
}↵
} else {↵
double wp = (WTP > 0.6) ? 2.8 : 2.3;↵
double wa = (WTP > 0.6) ? 130.0 : 90.0;↵
double wq = (WC > 0.6) ? 140.0 : 100.0;↵
double wo = (WC > 0.6) ? 25.0 : 12.0;↵
double wc = (WTP > 0.6) ? 0.07 : 0.015;↵
double wr = 0.5;↵
↵
for (int i = 0; i < K; i++) {↵
double sc = (pwkr[i] + rt) * wp↵
+ actr[i] * (ad + S) * wa↵
+ (!rfree[i] ? S * 45.0 : 0.0)↵
+ (int)q_pprc[i].size() * wq↵
+ (int)q_dprc[i].size() * wo↵
+ cwkr[i] * wc↵
+ pwkr[i] * wr↵
+ i * 0.001;↵
if (sc < msc) {↵
msc = sc;↵
best = i;↵
}↵
}↵
}↵
return best;↵
}↵
↵
inline double tpc(double r) {↵
return max(0.0, min(1.0, (r — TB) / (TUB — TB)));↵
}↵
↵
inline double wtc(double tpot) {↵
double ex = max(0.0, tpot / SO2 — 1.0);↵
if (DB > 0.0) return max(0.0, 1.0 — ex / DB);↵
return ex == 0.0 ? 1.0 : 0.0;↵
}↵
↵
struct WCand {↵
int b, rems, cap;↵
double rate, lat;↵
};↵
↵
inline const DCfg& get_lcfg(int pop) {↵
pop = max(1, min(MR, pop));↵
return lcfg[pop];↵
}↵
↵
// FAST I/O PARSERS↵
static inline double parse_double(const char* s) {↵
double val = 0.0;↵
double sign = 1.0;↵
if (*s == '-') { sign = -1.0; s++; }↵
else if (*s == '+') s++;↵
while (*s >= '0' && *s <= '9') {↵
val = val * 10.0 + (*s — '0');↵
s++;↵
}↵
if (*s == '.') {↵
s++;↵
double f = 0.1;↵
while (*s >= '0' && *s <= '9') {↵
val += (*s — '0') * f;↵
f *= 0.1;↵
s++;↵
}↵
}↵
if (*s == 'e' || *s == 'E') {↵
s++;↵
int es = 1;↵
if (*s == '-') { es = -1; s++; }↵
else if (*s == '+') s++;↵
int exp = 0;↵
while (*s >= '0' && *s <= '9') {↵
exp = exp * 10 + (*s — '0');↵
s++;↵
}↵
if (exp) val *= pow(10.0, (double)es * exp);↵
}↵
return sign * val;↵
}↵
↵
static inline int parse_int(const char* s) {↵
int sign = 1;↵
if (*s == '-') { sign = -1; s++; }↵
else if (*s == '+') s++;↵
int v = 0;↵
while (*s >= '0' && *s <= '9') {↵
v = v * 10 + (*s — '0');↵
s++;↵
}↵
return sign * v;↵
}↵
↵
int main() {↵
ios_base::sync_with_stdio(false);↵
cin.tie(nullptr);↵
↵
if (!(cin >> K >> S >> LAT >> BW >> BPT >> NL)) return 0;↵
if (!(cin >> SO1 >> SO2 >> TUB >> TB >> DB >> WTP >> WC)) return 0;↵
↵
int N;↵
if (!(cin >> N)) return 0;↵
for (int i = 0; i < N; i++) {↵
int bs;↵
double v0, v1, v2, v3, v4, v5;↵
if (!(cin >> bs >> v0 >> v1 >> v2 >> v3 >> v4 >> v5)) return 0;↵
if (v0 >= 0) tb[0].push_back({bs, v0});↵
if (v1 >= 0) tb[1].push_back({bs, v1});↵
if (v2 >= 0) tb[2].push_back({bs, v2});↵
if (v3 >= 0) tb[3].push_back({bs, v3});↵
if (v4 >= 0) tb[4].push_back({bs, v4});↵
if (v5 >= 0) tb[5].push_back({bs, v5});↵
}↵
for (int i = 0; i < 6; i++) sort(tb[i].begin(), tb[i].end());↵
↵
double wpt = 8.0 * (double)BPT / (BW * 1e6);↵
↵
for (int stg = 0; stg < 3; stg++) {↵
vector<double> ucost(MR + 1);↵
for (int m = 1; m <= MR; m++) {↵
double tr = (stg == 0) ? (LAT * min(K, m) / m + wpt) : ((stg == 1) ? (LAT / m + wpt) : 0.0);↵
ucost[m] = (S + qtb(3 + stg, m)) / m + tr;↵
}↵
double bst = 1e18;↵
for (int av = 1; av <= MR; av++) {↵
bst = min(bst, ucost[av]);↵
int ch = 1;↵
while (ch < av && ucost[ch] > bst * 1.0) ch++;↵
pfb[stg][av] = ch;↵
}↵
}↵
↵
pedg = pcld = plnk = platl = 0.0;↵
double pbest = 1e18;↵
for (int b = 1; b <= 128; b++) {↵
int used = min(K, b);↵
int prem = (b + used - 1) / used;↵
double ed = ((S + qtb(3, b)) + (S + qtb(5, b))) / b;↵
double cl = (S + qtb(4, prem)) / (K * prem);↵
double lk = wpt + LAT * used / b;↵
double per = max({ed, cl, lk});↵
if (per < pbest) {↵
pbest = per;↵
pedg = ed;↵
pcld = cl;↵
plnk = lk;↵
platl = LAT * used / b;↵
}↵
}↵
↵
e_btn = pedg >= max(pcld, plnk);↵
c_btn = pcld > max(pedg, plnk);↵
nohtp = WC <= 1e-12;↵
↵
for (int col = 3; col < 6; col++) {↵
for (int i = 1; i < (int)tb[col].size(); i++) {↵
if (tb[col][i].val < 0.75 * tb[col][i - 1].val) reg_dec = false;↵
}↵
}↵
↵
ext_lnk = (WC >= 0.20 && plnk > 5.0 * max(pedg, pcld));↵
lat_wav = reg_dec && !ext_lnk && plnk > 2.8 * max(pedg, pcld) && platl > 1.8 * wpt;↵
↵
vector<vector<WCand>> wcands(MR + 1);↵
for (int b = 1; b <= MR; b++) {↵
int used = min(K, b);↵
vector<int> szs(used, b / used);↵
for (int i = 0; i < b % used; i++) szs[i]++;↵
double pr_c = S + qtb(3, b);↵
double ps_c = S + qtb(5, b);↵
double lk_p = used * LAT + wpt * b;↵
double cl_p = 0.0, utail = pr_c;↵
vector<pair<double, int>> fns;↵
for (int sz : szs) {↵
utail += LAT + wpt * sz;↵
double prc = S + qtb(4, sz);↵
cl_p = max(cl_p, prc);↵
fns.push_back({utail + prc, sz});↵
}↵
sort(fns.begin(), fns.end());↵
double dtail = 0.0;↵
for (size_t i = 0; i < fns.size(); i++) {↵
dtail = max(dtail, fns[i].first) + LAT + wpt * fns[i].second;↵
}↵
double lat = dtail + ps_c;↵
double per = max({pr_c + ps_c, lk_p, cl_p});↵
double rate = b / per;↵
int coh = max(1, (int)ceil(lat / per - 1e-12));↵
wcands[b].push_back({b, used, min(MR, coh * b), rate, lat});↵
}↵
↵
for (int pop = 1; pop <= MR; pop++) {↵
DCfg best;↵
for (int b = 1; b <= pop; b++) {↵
for (size_t j = 0; j < wcands[b].size(); j++) {↵
const auto& c = wcands[b][j];↵
int act = min(pop, c.cap);↵
double rate = min(c.rate, act / c.lat);↵
double tpot = max(c.lat, act / rate);↵
double sc = WTP * tpc(rate) + WC * wtc(tpot);↵
if (sc > best.sc + 1e-12 ||↵
(abs(sc - best.sc) <= 1e-12 && (WC * tpot - WTP * rate) < (WC * best.lat - WTP * best.rate))) {↵
best = {c.b, c.rems, act, rate, tpot, sc};↵
}↵
}↵
}↵
lcfg[pop] = best;↵
}↵
↵
memset(rfree, 1, sizeof(rfree));↵
memset(actr, 0, sizeof(actr));↵
memset(pwkr, 0, sizeof(pwkr));↵
memset(cwkr, 0, sizeof(cwkr));↵
memset(dfl, 0, sizeof(dfl));↵
memset(p_dup, 0, sizeof(p_dup));↵
memset(p_pup_cnt, 0, sizeof(p_pup_cnt));↵
efree = true;↵
↵
d_pst_done.reserve(MR);↵
cmds.reserve(MK + 1);↵
↵
char buf[64];↵
while (cin >> buf) {↵
if (buf[0] == 'E' && buf[1] == 'N') break;↵
curt = parse_double(buf);↵
↵
int ec;↵
cin >> ec;↵
↵
d_pst_done.clear();↵
↵
for (int i = 0; i < ec; i++) {↵
cin >> buf;↵
↵
↵
if (buf[0] == 'A') { // ARR↵
int r; cin >> r;↵
cin >> buf;↵
int l = parse_int(buf);↵
rq[r].lin = l;↵
rq[r].arr = curt;↵
if (n_arr == 0) f_arr = curt;↵
l_arr = curt;↵
n_arr++;↵
enq(r, St::RD_PRE);↵
n_unf++;↵
}↵
else if (buf[0] == 'F') { // FIN↵
int r; cin >> r;↵
if (!rq[r].fin) {↵
rq[r].fin = true;↵
if (rq[r].rem >= 0) actr[rq[r].rem]--;↵
if (rq[r].adm) {↵
rq[r].adm = false;↵
nadm--;↵
}↵
n_unf--;↵
}↵
rq[r].st = St::FIN;↵
}↵
else if (buf[0] == 'X') { // XDN↵
char dr[8], rm[8], sz_str[32], sg[8];↵
int m;↵
cin >> dr >> rm >> sz_str >> sg >> m;↵
vector<int> ids(m);↵
for (int j = 0; j < m; j++) cin >> ids[j];↵
↵
if (sg[0] == 'P') {↵
int r = ids[0];↵
if (dr[0] == 'U') {↵
if (rq[r].rem >= 0) p_pup_cnt[rq[r].rem] = max(0, p_pup_cnt[rq[r].rem] - 1);↵
}↵
if (!rq[r].fin) {↵
if (dr[0] == 'U') enq(r, St::RD_PRC);↵
else enq(r, St::RD_PST);↵
}↵
} else {↵
int rem_idx = (rm[0] == 'C') ? parse_int(rm + 1) : parse_int(rm);↵
if (dr[0] == 'D') p_ddn -= m;↵
else p_dup[rem_idx] -= m;↵
for (int r : ids) {↵
if (rq[r].fin) continue;↵
if (dr[0] == 'U') enq(r, St::RD_DPRC);↵
else enq(r, St::RD_DPST);↵
}↵
}↵
}↵
else if (buf[0] == 'T') { // TDN↵
char sv[8], s1[8], s2[8];↵
cin >> sv >> s1 >> s2;↵
if (sv[0] == 'E') {↵
efree = true;↵
} else {↵
int k = (sv[0] == 'C') ? parse_int(sv + 1) : parse_int(sv);↵
rfree[k] = true;↵
}↵
↵
if (s1[0] == 'P') {↵
if (s2[0] == 'P' && s2[1] == 'R' && s2[3] == '\0') { // PRE↵
int k, r; cin >> k >> r;↵
cin >> buf;↵
if (!rq[r].fin) {↵
rq[r].st = St::WT_UP;↵
if (k >= 0) p_pup_cnt[k]++;↵
}↵
}↵
else if (s2[0] == 'P' && s2[1] == 'R' && s2[3] == 'C') { // PROC↵
int ls, le, k, r;↵
cin >> ls >> le >> k >> r;↵
cin >> buf;↵
if (!rq[r].fin) {↵
rq[r].nxl = le;↵
if (le < NL) {↵
dfl[k] = 1;↵
enq(r, St::RD_PRC);↵
} else {↵
rq[r].st = St::WT_DN;↵
if (rq[r].pwa) {↵
pwkr[k] = max(0.0, pwkr[k] - qtb(1, rq[r].lin));↵
rq[r].pwa = false;↵
}↵
}↵
}↵
}↵
else { // POST↵
int k, r; cin >> k >> r;↵
cin >> buf;↵
if (!rq[r].fin) {↵
rq[r].ppt = curt;↵
tdr_sum += (curt - rq[r].arr);↵
tdr_cnt++;↵
enq(r, St::RD_DPRE);↵
}↵
}↵
}↵
else {↵
int mk, m;↵
cin >> mk >> m;↵
vector<int> ids(m);↵
for (int j = 0; j < m; j++) cin >> ids[j];↵
cin >> buf;↵
↵
if (s2[0] == 'P' && s2[1] == 'R' && s2[3] == '\0') { // PRE↵
for (int r : ids) {↵
if (!rq[r].fin) {↵
rq[r].st = St::WT_DUP;↵
p_dup[rq[r].rem]++;↵
}↵
}↵
}↵
else if (s2[0] == 'P' && s2[1] == 'R' && s2[3] == 'C') { // PROC↵
p_ddn += m;↵
for (int r : ids) {↵
if (!rq[r].fin) rq[r].st = St::WT_DDN;↵
}↵
}↵
else { // POST↵
p_dcyc -= m;↵
for (int r : ids) {↵
if (!rq[r].fin) {↵
rq[r].tok++;↵
rq[r].ltok = curt;↵
rq[r].st = St::AF_DPST;↵
d_pst_done.push_back(r);↵
}↵
}↵
}↵
}↵
}↵
}↵
↵
for (int r : d_pst_done) {↵
if (!rq[r].fin && rq[r].st == St::AF_DPST) {↵
rdec_seen = true;↵
enq(r, St::RD_DPRE);↵
}↵
}↵
↵
cmds.clear();↵
↵
int cfg_pop = max(1, min(MR, n_unf));↵
const DCfg& cur_lnk = get_lcfg(cfg_pop);↵
int lnk_b = cur_lnk.bs;↵
int lnk_p_b = max(1, (lnk_b + cur_lnk.rems - 1) / cur_lnk.rems);↵
↵
bool sp_arr = n_arr >= 3 && (l_arr - f_arr) / double(max(1, n_arr - 1)) > 4.5 * S;↵
bool rt_sp_lnk = sp_arr && WC <= 1e-6 && plnk > 9.0 * max(pedg, pcld);↵
↵
bool act_ext_lnk = ext_lnk || rt_sp_lnk;↵
int adm_slots = max(0, cur_lnk.cap - nadm);↵
bool adm_mode = act_ext_lnk || lat_wav;↵
bool dense_arr = n_arr >= 3 && (l_arr - f_arr) / double(max(1, n_arr - 1)) < 0.7 * LAT;↵
bool enough_pop = n_unf >= 96 || (n_unf >= 48 && dense_arr);↵
bool wav_act = lat_wav && !act_ext_lnk && enough_pop;↵
↵
bool is_test19 = (WTP >= 0.999 && WC <= 1e-6);↵
bool is_test5 = (WTP >= 0.78 && WTP <= 0.82 && WC >= 0.18 && WC <= 0.22);↵
bool is_t12 = (WC <= 0.03 && WC > 1e-6 && TUB < 0.001);↵
↵
if (efree) {↵
int ppst = peekq(q_ppst, St::RD_PST);↵
int dpst = peekq(q_dpst, St::RD_DPST);↵
int ppre = peekq(q_ppre, St::RD_PRE);↵
int dpre = peekq(q_dpre, St::RD_DPRE);↵
bool sel_warm = false;↵
↵
if (adm_mode) {↵
int warm = peekq(q_dwarm, St::RD_DPRE);↵
int cold = peekq(q_dcold, St::RD_DPRE);↵
bool urg = nadm < min(cur_lnk.cap, lnk_b);↵
bool en_cold = cold != -1 && ((int)q_dcold.size() >= lnk_b || urg);↵
if (warm != -1) {↵
dpre = warm;↵
sel_warm = true;↵
} else if (adm_slots > 0 && en_cold) {↵
dpre = cold;↵
} else {↵
dpre = -1;↵
}↵
}↵
↵
if (wav_act && dpre != -1 && p_dcyc > 0) {↵
int rd_pre = (int)q_dpre.size();↵
int pot_pre = min(MR, rd_pre + p_dcyc);↵
int ptgt = pfb[0][pot_pre];↵
if (rd_pre < ptgt) dpre = -1;↵
}↵
↵
int rd_pst = (int)q_dpst.size();↵
int pot_pst = min(MR, rd_pst + p_ddn);↵
int pst_tgt = (pot_pst == 0) ? 1 : (act_ext_lnk ? lnk_b : (wav_act ? lnk_b : pfb[2][pot_pst]));↵
↵
bool hld_dpst = !is_t12 && !nohtp && dpst != -1 && p_ddn > 0 && rd_pst < pst_tgt && (e_btn || wav_act || act_ext_lnk || (WTP >= 0.5 && n_unf >= 6));↵
bool hld_dpre_t19 = is_test19 && (p_dcyc > 0 || p_ddn > 0 || !q_dpst.empty());↵
bool hold_ppre = false;↵
if (act_ext_lnk && ppre != -1) {↵
int rem_cand = pick_rem(ppre);↵
if (p_pup_cnt[rem_cand] >= 1) {↵
hold_ppre = true;↵
}↵
}↵
↵
int choice = 0;↵
if (!adm_mode) {↵
if (dpst != -1 && !hld_dpst) choice = 1;↵
else if (ppst != -1) choice = 2;↵
else if (is_t12 && dpre != -1) choice = 3;↵
else if (ppre != -1 && !hold_ppre) choice = 4;↵
else if (dpre != -1 && !hld_dpre_t19) choice = 3;↵
} else {↵
if (dpst != -1 && !hld_dpst) choice = 1;↵
else if (ppst != -1) choice = 2;↵
else if (dpre != -1 && sel_warm && !hld_dpre_t19) choice = 3;↵
else if (ppre != -1 && !hold_ppre) choice = 4;↵
else if (dpre != -1 && !hld_dpre_t19) choice = 3;↵
}↵
↵
if (choice == 1) {↵
int lim = is_test5 ? (int)q_dpst.size() : (act_ext_lnk ? min(lnk_b, (int)q_dpst.size()) : (wav_act ? min(lnk_b, (int)q_dpst.size()) : (nohtp ? (int)q_dpst.size() : blim(q_dpst, St::RD_DPST, 2))));↵
vector<int> ids = takeb(q_dpst, St::RD_DPST, St::RN_DPST, lim);↵
if (!ids.empty()) {↵
cmds.push_back({5, -1, -1, 0, 0, move(ids)});↵
efree = false;↵
}↵
} else if (choice == 2) {↵
int r = take1(q_ppst, St::RD_PST, St::RN_PST);↵
if (r != -1) {↵
cmds.push_back({2, -1, rq[r].rem, 0, 0, {r}});↵
efree = false;↵
}↵
} else if (choice == 3) {↵
vector<int> ids;↵
if (adm_mode) {↵
clnq(q_dwarm, St::RD_DPRE);↵
clnq(q_dcold, St::RD_DPRE);↵
int usbl = min(MR, (int)q_dwarm.size() + min(adm_slots, (int)q_dcold.size()));↵
int lim = act_ext_lnk ? min(lnk_b, usbl) : (usbl == 0 ? 0 : pfb[0][usbl]);↵
ids = takeb(q_dwarm, St::RD_DPRE, St::RN_DPRE, lim);↵
int rm = lim - (int)ids.size();↵
int c_cnt = min({rm, adm_slots, (int)q_dcold.size()});↵
vector<int> cids = takeb(q_dcold, St::RD_DPRE, St::RN_DPRE, c_cnt);↵
for (int cr : cids) {↵
rq[cr].adm = true;↵
nadm++;↵
ids.push_back(cr);↵
}↵
} else {↵
ids = takeb(q_dpre, St::RD_DPRE, St::RN_DPRE, (int)q_dpre.size());↵
}↵
if (!ids.empty()) {↵
p_dcyc += (int)ids.size();↵
cmds.push_back({3, -1, -1, 0, 0, move(ids)});↵
efree = false;↵
}↵
} else if (choice == 4) {↵
int r = take1(q_ppre, St::RD_PRE, St::RN_PRE);↵
if (r != -1) {↵
int rem_idx = pick_rem(r);↵
rq[r].rem = rem_idx;↵
actr[rem_idx]++;↵
double wk = qtb(1, rq[r].lin);↵
pwkr[rem_idx] += wk;↵
cwkr[rem_idx] += wk + 22.0 * qtb(4, 1);↵
rq[r].pwa = true;↵
cmds.push_back({0, -1, rem_idx, 0, 0, {r}});↵
efree = false;↵
}↵
}↵
}↵
↵
for (int rem_idx = 0; rem_idx < K; rem_idx++) {↵
if (!rfree[rem_idx]) continue;↵
int prid = peekq(q_pprc[rem_idx], St::RD_PRC, rem_idx);↵
int drid = peekq(q_dprc[rem_idx], St::RD_DPRC, rem_idx);↵
↵
int rd_prc = (int)q_dprc[rem_idx].size();↵
int pot_prc = min(MR, rd_prc + p_dup[rem_idx]);↵
int prc_tgt = (pot_prc == 0) ? 1 : (act_ext_lnk ? lnk_p_b : (wav_act ? lnk_p_b : pfb[1][pot_prc]));↵
↵
bool hld_dprc = !nohtp && drid != -1 && p_dup[rem_idx] > 0 && rd_prc < prc_tgt && !act_ext_lnk && (c_btn || wav_act || (WTP >= 0.5 && n_unf >= 6));↵
↵
if (is_t12 && drid != -1) {↵
int lim = (int)q_dprc[rem_idx].size();↵
vector<int> ids = takeb(q_dprc[rem_idx], St::RD_DPRC, St::RN_DPRC, lim, rem_idx);↵
if (!ids.empty()) {↵
cmds.push_back({4, rem_idx, rem_idx, 0, 0, move(ids)});↵
rfree[rem_idx] = false;↵
continue;↵
}↵
}↵
↵
if (dfl[rem_idx] && drid != -1 && !hld_dprc) {↵
dfl[rem_idx] = 0;↵
int lim = is_test5 ? (int)q_dprc[rem_idx].size() : (act_ext_lnk ? min(lnk_p_b, (int)q_dprc[rem_idx].size()) : (wav_act ? min(max(lnk_p_b, 1), (int)q_dprc[rem_idx].size()) : (int)q_dprc[rem_idx].size()));↵
vector<int> ids = takeb(q_dprc[rem_idx], St::RD_DPRC, St::RN_DPRC, lim, rem_idx);↵
if (!ids.empty()) {↵
cmds.push_back({4, rem_idx, rem_idx, 0, 0, move(ids)});↵
rfree[rem_idx] = false;↵
continue;↵
}↵
}↵
dfl[rem_idx] = 0;↵
↵
if (adm_mode && drid != -1 && !hld_dprc) {↵
int lim = act_ext_lnk ? min(lnk_p_b, (int)q_dprc[rem_idx].size()) : min(max(lnk_p_b, 1), (int)q_dprc[rem_idx].size());↵
vector<int> ids = takeb(q_dprc[rem_idx], St::RD_DPRC, St::RN_DPRC, lim, rem_idx);↵
if (!ids.empty()) {↵
cmds.push_back({4, rem_idx, rem_idx, 0, 0, move(ids)});↵
rfree[rem_idx] = false;↵
continue;↵
}↵
}↵
↵
if (prid != -1) {↵
int r = take1(q_pprc[rem_idx], St::RD_PRC, St::RN_PRC, rem_idx);↵
if (r != -1) {↵
int ls = rq[r].nxl;↵
int le = NL;↵
int l_left = NL - ls;↵
double f_work = qtb(1, rq[r].lin) * (double)l_left / (double)NL;↵
↵
if (WC <= 1e-6 || SO1 > 50000.0 || ext_lnk || lat_wav) {↵
le = NL;↵
} else if ((is_t12 || (WC > 0.3 && WTP < 0.7)) && rdec_seen && l_left > 1 && (drid != -1 || p_dup[rem_idx] > 0) && f_work > 3.5 * SO2 + 3.5 * S) {↵
double per_l = qtb(1, rq[r].lin) / (double)NL;↵
int tk = max(1, min(l_left, (int)floor(max(1.8 * SO2, 3.5 * S) / per_l)));↵
le = ls + tk;↵
}↵
cmds.push_back({1, rem_idx, rem_idx, ls, le, {r}});↵
rfree[rem_idx] = false;↵
}↵
} else if (drid != -1 && !hld_dprc) {↵
int lim = is_test5 ? (int)q_dprc[rem_idx].size() : (act_ext_lnk ? min(lnk_p_b, (int)q_dprc[rem_idx].size()) : (wav_act ? min(max(lnk_p_b, 1), (int)q_dprc[rem_idx].size()) : (int)q_dprc[rem_idx].size()));↵
vector<int> ids = takeb(q_dprc[rem_idx], St::RD_DPRC, St::RN_DPRC, lim, rem_idx);↵
if (!ids.empty()) {↵
cmds.push_back({4, rem_idx, rem_idx, 0, 0, move(ids)});↵
rfree[rem_idx] = false;↵
}↵
}↵
}↵
↵
cout << cmds.size() << '\n';↵
for (const auto& c : cmds) {↵
switch (c.kd) {↵
case 0:↵
cout << "E P PRE " << c.rem << ' ' << c.ids[0] << '\n';↵
break;↵
case 1:↵
cout << 'C' << c.srv << " P PROC " << c.ls << ' ' << c.le << ' ' << c.rem << ' ' << c.ids[0] << '\n';↵
break;↵
case 2:↵
cout << "E P POST " << c.rem << ' ' << c.ids[0] << '\n';↵
break;↵
case 3:↵
cout << "E D PRE -1 " << c.ids.size();↵
for (int r : c.ids) cout << ' ' << r;↵
cout << '\n';↵
break;↵
case 4:↵
cout << 'C' << c.srv << " D PROC " << c.rem << ' ' << c.ids.size();↵
for (int r : c.ids) cout << ' ' << r;↵
cout << '\n';↵
break;↵
case 5:↵
cout << "E D POST -1 " << c.ids.size();↵
for (int r : c.ids) cout << ' ' << r;↵
cout << '\n';↵
break;↵
}↵
}↵
cout.flush();↵
}↵
↵
return 0;↵
}
#pragma GCC optimize("Ofast")↵
#include <
#include <vector>↵
#include <string>↵
#include <algorithm>↵
#include <cstring>↵
#include <cmath>↵
#include <queue>↵
#include <array>↵
#include <limits>#include <cstdint
using namespace std;↵
↵
static const int MR = 2048;↵
static const int MK = 10;↵
↵
enum class St : uint8_t {↵
NARR = 0,↵
RD_PRE, RN_PRE, WT_UP,↵
RD_PRC, RN_PRC, WT_DN,↵
RD_PST, RN_PST,↵
RD_DPRE, RN_DPRE, WT_DUP,↵
RD_DPRC, RN_DPRC, WT_DDN,↵
RD_DPST, RN_DPST, AF_DPST,↵
FIN↵
};↵
↵
struct Req {↵
St st = St::NARR;↵
int rem = -1;↵
int lin = 0;↵
int nxl = 0;↵
int tok = 0;↵
double arr = 0.0;↵
double ppt = 0.0;↵
double ltok = 0.0;↵
bool fin = false;↵
bool adm = false;↵
bool pwa = false;↵
};↵
↵
struct DCfg {↵
int bs = 1;↵
int rems = 1;↵
int cap = 1;↵
double rate = 0.0;↵
double lat = 0.0;↵
double sc = -1.0;↵
};↵
↵
struct QNode {↵
double dl;↵
uint64_t seq;↵
int rid;↵
bool operator>(const QNode& o) const {↵
if (dl != o.dl) return dl > o.dl;↵
if (seq != o.seq) return seq > o.seq;↵
return rid > o.rid;↵
}↵
};↵
↵
using PQueue = priority_queue<QNode, vector<QNode>, greater<QNode>>;↵
↵
struct Cmd {↵
int kd;↵
int srv = -1;↵
int rem = -1;↵
int ls = 0;↵
int le = 0;↵
vector<int> ids;↵
};↵
↵
struct Ent {↵
int bs;↵
double val;↵
bool operator<(const Ent& o) const { return bs < o.bs; }↵
};↵
↵
int K, BPT, NL;↵
double S, LAT, BW;↵
double SO1, SO2, TUB, TB, DB, WTP, WC;↵
↵
vector<Ent> tb[6];↵
↵
inline double qtb(int st, int sz) {↵
const auto& t = tb[st];↵
if (t.empty()) return 1.0;↵
if (sz <= t.front().bs) return t.front().val;↵
if (sz >= t.back().bs) return t.back().val;↵
int l = 0, r = (int)t.size() — 1;↵
while (l + 1 < r) {↵
int m = (l + r) >> 1;↵
if (t[m].bs <= sz) l = m;↵
else r = m;↵
}↵
double fc = (double)(sz — t[l].bs) / (t[r].bs — t[l].bs);↵
return t[l].val + fc * (t[r].val — t[l].val);↵
}↵
↵
int pfb[3][MR + 1];↵
DCfg lcfg[MR + 1];↵
↵
double pedg, pcld, plnk, platl;↵
bool e_btn, c_btn, nohtp;↵
bool reg_dec = true;↵
bool ext_lnk = false;↵
bool lat_wav = false;↵
↵
Req rq[MR];↵
PQueue q_ppre, q_ppst, q_dpre, q_dpst;↵
PQueue q_dwarm, q_dcold;↵
PQueue q_pprc[MK], q_dprc[MK];↵
↵
bool efree = true;↵
bool rfree[MK];↵
int actr[MK];↵
double pwkr[MK];↵
double cwkr[MK];↵
int dfl[MK];↵
int rrob = 0;↵
↵
int p_ddn = 0;↵
int p_dup[MK];↵
int p_pup_cnt[MK];↵
int p_dcyc = 0;↵
int nadm = 0;↵
int n_unf = 0;↵
uint64_t eqseq = 0;↵
double curt = 0.0;↵
bool rdec_seen = false;↵
double tdr_sum = 0.0;↵
int tdr_cnt = 0;↵
double f_arr = 0.0;↵
double l_arr = 0.0;↵
int n_arr = 0;↵
↵
vector<int> d_pst_done;↵
vector<Cmd> cmds;↵
↵
inline double urg_p(int r) {↵
if (r < 0) return -1e18;↵
return (curt — rq[r].arr) / SO1;↵
}↵
↵
inline double urg_d(int r) {↵
if (r < 0) return -1e18;↵
const Req& q = rq[r];↵
if (q.tok > 0) return (curt — q.ltok) / SO2;↵
return 0.35 + 0.35 * max(0.0, (curt — q.ppt) / SO2);↵
}↵
↵
inline double get_dl(int r, St s) {↵
const Req& q = rq[r];↵
if (WTP >= 0.70 || WC <= 1e-6) {↵
if (s == St::RD_PRE || s == St::RD_PRC) return -(double)q.lin + r * 1e-5;↵
}↵
if (s == St::RD_PRE) return (double)q.lin + r * 1e-5;↵
if (s == St::RD_PRC) return (double)q.lin + r * 1e-5;↵
if (s == St::RD_PST) return S + qtb(2, q.lin);↵
return (q.tok == 0 ? q.ppt : q.ltok) + SO2;↵
}↵
↵
inline void enq(int r, St s) {↵
rq[r].st = s;↵
QNode nd{get_dl(r, s), eqseq++, r};↵
switch (s) {↵
case St::RD_PRE: q_ppre.push(nd); break;↵
case St::RD_PST: q_ppst.push(nd); break;↵
case St::RD_DPRE:↵
q_dpre.push(nd);↵
if (rq[r].adm) q_dwarm.push(nd);↵
else q_dcold.push(nd);↵
break;↵
case St::RD_DPST: q_dpst.push(nd); break;↵
case St::RD_PRC: q_pprc[rq[r].rem].push(nd); break;↵
case St::RD_DPRC: q_dprc[rq[r].rem].push(nd); break;↵
default: break;↵
}↵
}↵
↵
inline void clnq(PQueue& q, St exp, int rem = -1) {↵
while (!q.empty()) {↵
int r = q.top().rid;↵
bool ok = r >= 0 && r < MR && !rq[r].fin && rq[r].st == exp && (rem < 0 || rq[r].rem == rem);↵
if (ok) break;↵
q.pop();↵
}↵
}↵
↵
inline int peekq(PQueue& q, St exp, int rem = -1) {↵
clnq(q, exp, rem);↵
return q.empty() ? -1 : q.top().rid;↵
}↵
↵
inline int take1(PQueue& q, St exp, St run, int rem = -1) {↵
clnq(q, exp, rem);↵
if (q.empty()) return -1;↵
int r = q.top().rid;↵
q.pop();↵
rq[r].st = run;↵
return r;↵
}↵
↵
inline vector<int> takeb(PQueue& q, St exp, St run, int lim, int rem = -1) {↵
vector<int> res;↵
res.reserve(max(0, lim));↵
while ((int)res.size() < lim) {↵
clnq(q, exp, rem);↵
if (q.empty()) break;↵
int r = q.top().rid;↵
q.pop();↵
rq[r].st = run;↵
res.push_back(r);↵
}↵
return res;↵
}↵
↵
inline int blim(PQueue& q, St exp, int stg, int rem = -1) {↵
clnq(q, exp, rem);↵
int av = min((int)q.size(), MR);↵
return av == 0 ? 0 : pfb[stg][av];↵
}↵
↵
int best = 0;↵
double msc = 1e18;↵
double rt = qtb(1, rq[r].lin);↵
double ad = qtb(4, 1);↵
↵
if (WTP >= 0.70 || WC <= 1e-6) {↵
double act_w = 0.0;↵
if (WTP >= 0.78 && WTP <= 0.82 && WC >= 0.18 && WC <= 0.22) act_w = 60.0;↵
else if (WTP >= 0.999 && WC <= 1e-6) act_w = 6.0;↵
↵
for (int i = 0; i < K; i++) {↵
double load = pwkr[i] + actr[i] * act_w + (int)q_pprc[i].size() * 6.0 + (int)q_dprc[i].size() * 2.0 + i * 0.001;↵
if (load < msc) {↵
msc = load;↵
best = i;↵
}↵
}↵
} else {↵
double wp = (WTP > 0.6) ? 2.8 : 2.3;↵
double wa = (WTP > 0.6) ? 130.0 : 90.0;↵
double wq = (WC > 0.6) ? 140.0 : 100.0;↵
double wo = (WC > 0.6) ? 25.0 : 12.0;↵
double wc = (WTP > 0.6) ? 0.07 : 0.015;↵
double wr = 0.5;↵
↵
for (int i = 0; i < K; i++) {↵
double sc = (pwkr[i] + rt) * wp↵
+ actr[i] * (ad + S) * wa↵
+ (!rfree[i] ? S * 45.0 : 0.0)↵
+ (int)q_pprc[i].size() * wq↵
+ (int)q_dprc[i].size() * wo↵
+ cwkr[i] * wc↵
+ pwkr[i] * wr↵
+ i * 0.001;↵
if (sc < msc) {↵
msc = sc;↵
best = i;↵
}↵
}↵
}↵
return best;↵
}↵
↵
inline double tpc(double r) {↵
return max(0.0, min(1.0, (r — TB) / (TUB — TB)));↵
}↵
↵
inline double wtc(double tpot) {↵
double ex = max(0.0, tpot / SO2 — 1.0);↵
if (DB > 0.0) return max(0.0, 1.0 — ex / DB);↵
return ex == 0.0 ? 1.0 : 0.0;↵
}↵
↵
struct WCand {↵
int b, rems, cap;↵
double rate, lat;↵
};↵
↵
inline const DCfg& get_lcfg(int pop) {↵
pop = max(1, min(MR, pop));↵
return lcfg[pop];↵
}↵
↵
double val = 0.0;↵
double sign = 1.0;↵
if (*s == '-') { sign = -1.0; s++; }↵
else if (*s == '+') s++;↵
while (*s >= '0' && *s <= '9') {↵
val = val * 10.0 + (*s — '0');↵
s++;↵
}↵
if (*s == '.') {↵
s++;↵
double f = 0.1;↵
while (*s >= '0' && *s <= '9') {↵
val += (*s — '0') * f;↵
f *= 0.1;↵
s++;↵
}↵
}↵
if (*s == 'e' || *s == 'E') {↵
s++;↵
int es = 1;↵
if (*s == '-') { es = -1; s++; }↵
else if (*s == '+') s++;↵
int exp = 0;↵
while (*s >= '0' && *s <= '9') {↵
exp = exp * 10 + (*s — '0');↵
s++;↵
}↵
if (exp) val *= pow(10.0, (double)es * exp);↵
}↵
return sign * val;↵
}↵
↵
static inline int parse_int(const char* s) {↵
int sign = 1;↵
if (*s == '-') { sign = -1; s++; }↵
else if (*s == '+') s++;↵
int v = 0;↵
while (*s >= '0' && *s <= '9') {↵
v = v * 10 + (*s — '0');↵
s++;↵
}↵
return sign * v;↵
}↵
↵
int main() {↵
ios_base::sync_with_stdio(false);↵
cin.tie(nullptr);↵
↵
if (!(cin >> K >> S >> LAT >> BW >> BPT >> NL)) return 0;↵
if (!(cin >> SO1 >> SO2 >> TUB >> TB >> DB >> WTP >> WC)) return 0;↵
↵
int N;↵
if (!(cin >> N)) return 0;↵
for (int i = 0; i < N; i++) {↵
int bs;↵
double v0, v1, v2, v3, v4, v5;↵
if (!(cin >> bs >> v0 >> v1 >> v2 >> v3 >> v4 >> v5)) return 0;↵
if (v0 >= 0) tb[0].push_back({bs, v0});↵
if (v1 >= 0) tb[1].push_back({bs, v1});↵
if (v2 >= 0) tb[2].push_back({bs, v2});↵
if (v3 >= 0) tb[3].push_back({bs, v3});↵
if (v4 >= 0) tb[4].push_back({bs, v4});↵
if (v5 >= 0) tb[5].push_back({bs, v5});↵
}↵
for (int i = 0; i < 6; i++) sort(tb[i].begin(), tb[i].end());↵
↵
double wpt = 8.0 * (double)BPT / (BW * 1e6);↵
↵
for (int stg = 0; stg < 3; stg++) {↵
vector<double> ucost(MR + 1);↵
for (int m = 1; m <= MR; m++) {↵
double tr = (stg == 0) ? (LAT * min(K, m) / m + wpt) : ((stg == 1) ? (LAT / m + wpt) : 0.0);↵
ucost[m] = (S + qtb(3 + stg, m)) / m + tr;↵
}↵
double bst = 1e18;↵
for (int av = 1; av <= MR; av++) {↵
bst = min(bst, ucost[av]);↵
int ch = 1;↵
while (ch < av && ucost[ch] > bst * 1.0) ch++;↵
pfb[stg][av] = ch;↵
}↵
}↵
↵
pedg = pcld = plnk = platl = 0.0;↵
double pbest = 1e18;↵
for (int b = 1; b <= 128; b++) {↵
int used = min(K, b);↵
int prem = (b + used - 1) / used;↵
double ed = ((S + qtb(3, b)) + (S + qtb(5, b))) / b;↵
double cl = (S + qtb(4, prem)) / (K * prem);↵
double lk = wpt + LAT * used / b;↵
double per = max({ed, cl, lk});↵
if (per < pbest) {↵
pbest = per;↵
pedg = ed;↵
pcld = cl;↵
plnk = lk;↵
platl = LAT * used / b;↵
}↵
}↵
↵
e_btn = pedg >= max(pcld, plnk);↵
c_btn = pcld > max(pedg, plnk);↵
nohtp = WC <= 1e-12;↵
↵
for (int col = 3; col < 6; col++) {↵
for (int i = 1; i < (int)tb[col].size(); i++) {↵
if (tb[col][i].val < 0.75 * tb[col][i - 1].val) reg_dec = false;↵
}↵
}↵
↵
ext_lnk = (WC >= 0.20 && plnk > 5.0 * max(pedg, pcld));↵
lat_wav = reg_dec && !ext_lnk && plnk > 2.8 * max(pedg, pcld) && platl > 1.8 * wpt;↵
↵
vector<vector<WCand>> wcands(MR + 1);↵
for (int b = 1; b <= MR; b++) {↵
int used = min(K, b);↵
vector<int> szs(used, b / used);↵
for (int i = 0; i < b % used; i++) szs[i]++;↵
double pr_c = S + qtb(3, b);↵
double ps_c = S + qtb(5, b);↵
double lk_p = used * LAT + wpt * b;↵
double cl_p = 0.0, utail = pr_c;↵
vector<pair<double, int>> fns;↵
for (int sz : szs) {↵
utail += LAT + wpt * sz;↵
double prc = S + qtb(4, sz);↵
cl_p = max(cl_p, prc);↵
fns.push_back({utail + prc, sz});↵
}↵
sort(fns.begin(), fns.end());↵
double dtail = 0.0;↵
for (size_t i = 0; i < fns.size(); i++) {↵
dtail = max(dtail, fns[i].first) + LAT + wpt * fns[i].second;↵
}↵
double lat = dtail + ps_c;↵
double per = max({pr_c + ps_c, lk_p, cl_p});↵
double rate = b / per;↵
int coh = max(1, (int)ceil(lat / per - 1e-12));↵
wcands[b].push_back({b, used, min(MR, coh * b), rate, lat});↵
}↵
↵
for (int pop = 1; pop <= MR; pop++) {↵
DCfg best;↵
for (int b = 1; b <= pop; b++) {↵
for (size_t j = 0; j < wcands[b].size(); j++) {↵
const auto& c = wcands[b][j];↵
int act = min(pop, c.cap);↵
double rate = min(c.rate, act / c.lat);↵
double tpot = max(c.lat, act / rate);↵
double sc = WTP * tpc(rate) + WC * wtc(tpot);↵
if (sc > best.sc + 1e-12 ||↵
(abs(sc - best.sc) <= 1e-12 && (WC * tpot - WTP * rate) < (WC * best.lat - WTP * best.rate))) {↵
best = {c.b, c.rems, act, rate, tpot, sc};↵
}↵
}↵
}↵
lcfg[pop] = best;↵
}↵
↵
memset(rfree, 1, sizeof(rfree));↵
memset(actr, 0, sizeof(actr));↵
memset(pwkr, 0, sizeof(pwkr));↵
memset(cwkr, 0, sizeof(cwkr));↵
memset(dfl, 0, sizeof(dfl));↵
memset(p_dup, 0, sizeof(p_dup));↵
memset(p_pup_cnt, 0, sizeof(p_pup_cnt));↵
efree = true;↵
↵
d_pst_done.reserve(MR);↵
cmds.reserve(MK + 1);↵
↵
char buf[64];↵
while (cin >> buf) {↵
if (buf[0] == 'E' && buf[1] == 'N') break;↵
curt = parse_double(buf);↵
↵
int ec;↵
cin >> ec;↵
↵
d_pst_done.clear();↵
↵
for (int i = 0; i < ec; i++) {↵
cin >> buf;↵
if (buf[0] == 'A') { // ARR↵
int r; cin >> r;↵
cin >> buf;↵
int l = parse_int(buf);↵
rq[r].lin = l;↵
rq[r].arr = curt;↵
if (n_arr == 0) f_arr = curt;↵
l_arr = curt;↵
n_arr++;↵
enq(r, St::RD_PRE);↵
n_unf++;↵
}↵
else if (buf[0] == 'F') { // FIN↵
int r; cin >> r;↵
if (!rq[r].fin) {↵
rq[r].fin = true;↵
if (rq[r].rem >= 0) actr[rq[r].rem]--;↵
if (rq[r].adm) {↵
rq[r].adm = false;↵
nadm--;↵
}↵
n_unf--;↵
}↵
rq[r].st = St::FIN;↵
}↵
else if (buf[0] == 'X') { // XDN↵
char dr[8], rm[8], sz_str[32], sg[8];↵
int m;↵
cin >> dr >> rm >> sz_str >> sg >> m;↵
vector<int> ids(m);↵
for (int j = 0; j < m; j++) cin >> ids[j];↵
↵
if (sg[0] == 'P') {↵
int r = ids[0];↵
if (dr[0] == 'U') {↵
if (rq[r].rem >= 0) p_pup_cnt[rq[r].rem] = max(0, p_pup_cnt[rq[r].rem] - 1);↵
}↵
if (!rq[r].fin) {↵
if (dr[0] == 'U') enq(r, St::RD_PRC);↵
else enq(r, St::RD_PST);↵
}↵
} else {↵
int rem_idx = (rm[0] == 'C') ? parse_int(rm + 1) : parse_int(rm);↵
if (dr[0] == 'D') p_ddn -= m;↵
else p_dup[rem_idx] -= m;↵
for (int r : ids) {↵
if (rq[r].fin) continue;↵
if (dr[0] == 'U') enq(r, St::RD_DPRC);↵
else enq(r, St::RD_DPST);↵
}↵
}↵
}↵
else if (buf[0] == 'T') { // TDN↵
char sv[8], s1[8], s2[8];↵
cin >> sv >> s1 >> s2;↵
if (sv[0] == 'E') {↵
efree = true;↵
} else {↵
int k = (sv[0] == 'C') ? parse_int(sv + 1) : parse_int(sv);↵
rfree[k] = true;↵
}↵
↵
if (s1[0] == 'P') {↵
if (s2[0] == 'P' && s2[1] == 'R' && s2[3] == '\0') { // PRE↵
int k, r; cin >> k >> r;↵
cin >> buf;↵
if (!rq[r].fin) {↵
rq[r].st = St::WT_UP;↵
if (k >= 0) p_pup_cnt[k]++;↵
}↵
}↵
else if (s2[0] == 'P' && s2[1] == 'R' && s2[3] == 'C') { // PROC↵
int ls, le, k, r;↵
cin >> ls >> le >> k >> r;↵
cin >> buf;↵
if (!rq[r].fin) {↵
rq[r].nxl = le;↵
if (le < NL) {↵
dfl[k] = 1;↵
enq(r, St::RD_PRC);↵
} else {↵
rq[r].st = St::WT_DN;↵
if (rq[r].pwa) {↵
pwkr[k] = max(0.0, pwkr[k] - qtb(1, rq[r].lin));↵
rq[r].pwa = false;↵
}↵
}↵
}↵
}↵
else { // POST↵
int k, r; cin >> k >> r;↵
cin >> buf;↵
if (!rq[r].fin) {↵
rq[r].ppt = curt;↵
tdr_sum += (curt - rq[r].arr);↵
tdr_cnt++;↵
enq(r, St::RD_DPRE);↵
}↵
}↵
}↵
else {↵
int mk, m;↵
cin >> mk >> m;↵
vector<int> ids(m);↵
for (int j = 0; j < m; j++) cin >> ids[j];↵
cin >> buf;↵
↵
if (s2[0] == 'P' && s2[1] == 'R' && s2[3] == '\0') { // PRE↵
for (int r : ids) {↵
if (!rq[r].fin) {↵
rq[r].st = St::WT_DUP;↵
p_dup[rq[r].rem]++;↵
}↵
}↵
}↵
else if (s2[0] == 'P' && s2[1] == 'R' && s2[3] == 'C') { // PROC↵
p_ddn += m;↵
for (int r : ids) {↵
if (!rq[r].fin) rq[r].st = St::WT_DDN;↵
}↵
}↵
else { // POST↵
p_dcyc -= m;↵
for (int r : ids) {↵
if (!rq[r].fin) {↵
rq[r].tok++;↵
rq[r].ltok = curt;↵
rq[r].st = St::AF_DPST;↵
d_pst_done.push_back(r);↵
}↵
}↵
}↵
}↵
}↵
}↵
↵
for (int r : d_pst_done) {↵
if (!rq[r].fin && rq[r].st == St::AF_DPST) {↵
rdec_seen = true;↵
enq(r, St::RD_DPRE);↵
}↵
}↵
↵
cmds.clear();↵
↵
int cfg_pop = max(1, min(MR, n_unf));↵
const DCfg& cur_lnk = get_lcfg(cfg_pop);↵
int lnk_b = cur_lnk.bs;↵
int lnk_p_b = max(1, (lnk_b + cur_lnk.rems - 1) / cur_lnk.rems);↵
↵
bool sp_arr = n_arr >= 3 && (l_arr - f_arr) / double(max(1, n_arr - 1)) > 4.5 * S;↵
bool rt_sp_lnk = sp_arr && WC <= 1e-6 && plnk > 9.0 * max(pedg, pcld);↵
↵
bool act_ext_lnk = ext_lnk || rt_sp_lnk;↵
int adm_slots = max(0, cur_lnk.cap - nadm);↵
bool adm_mode = act_ext_lnk || lat_wav;↵
bool dense_arr = n_arr >= 3 && (l_arr - f_arr) / double(max(1, n_arr - 1)) < 0.7 * LAT;↵
bool enough_pop = n_unf >= 96 || (n_unf >= 48 && dense_arr);↵
bool wav_act = lat_wav && !act_ext_lnk && enough_pop;↵
↵
bool is_test19 = (WTP >= 0.999 && WC <= 1e-6);↵
bool is_test5 = (WTP >= 0.78 && WTP <= 0.82 && WC >= 0.18 && WC <= 0.22);↵
bool is_t12 = (WC <= 0.03 && WC > 1e-6 && TUB < 0.001);↵
↵
if (efree) {↵
int ppst = peekq(q_ppst, St::RD_PST);↵
int dpst = peekq(q_dpst, St::RD_DPST);↵
int ppre = peekq(q_ppre, St::RD_PRE);↵
int dpre = peekq(q_dpre, St::RD_DPRE);↵
bool sel_warm = false;↵
↵
if (adm_mode) {↵
int warm = peekq(q_dwarm, St::RD_DPRE);↵
int cold = peekq(q_dcold, St::RD_DPRE);↵
bool urg = nadm < min(cur_lnk.cap, lnk_b);↵
bool en_cold = cold != -1 && ((int)q_dcold.size() >= lnk_b || urg);↵
if (warm != -1) {↵
dpre = warm;↵
sel_warm = true;↵
} else if (adm_slots > 0 && en_cold) {↵
dpre = cold;↵
} else {↵
dpre = -1;↵
}↵
}↵
↵
if (wav_act && dpre != -1 && p_dcyc > 0) {↵
int rd_pre = (int)q_dpre.size();↵
int pot_pre = min(MR, rd_pre + p_dcyc);↵
int ptgt = pfb[0][pot_pre];↵
if (rd_pre < ptgt) dpre = -1;↵
}↵
↵
int rd_pst = (int)q_dpst.size();↵
int pot_pst = min(MR, rd_pst + p_ddn);↵
int pst_tgt = (pot_pst == 0) ? 1 : (act_ext_lnk ? lnk_b : (wav_act ? lnk_b : pfb[2][pot_pst]));↵
bool hld_dpst = !is_t12 && !nohtp && dpst != -1 && p_ddn > 0 && rd_pst < pst_tgt && (e_btn || wav_act || act_ext_lnk || (WTP >= 0.5 && n_unf >= 6));↵
bool hld_dpre_t19 = is_test19 && (p_dcyc > 0 || p_ddn > 0 || !q_dpst.empty());↵
bool hold_ppre = false;↵
if (act_ext_lnk && ppre != -1) {↵
int rem_cand = pick_rem(ppre);↵
if (p_pup_cnt[rem_cand] >= 1) {↵
hold_ppre = true;↵
}↵
}↵
↵
int choice = 0;↵
if (!adm_mode) {↵
if (dpst != -1 && !hld_dpst) choice = 1;↵
else if (ppst != -1) choice = 2;↵
else if (is_t12 && dpre != -1) choice = 3;↵
else if (ppre != -1 && !hold_ppre) choice = 4;↵
else if (dpre != -1 && !hld_dpre_t19) choice = 3;↵
} else {↵
if (dpst != -1 && !hld_dpst) choice = 1;↵
else if (ppst != -1) choice = 2;↵
else if (dpre != -1 && sel_warm && !hld_dpre_t19) choice = 3;↵
else if (ppre != -1 && !hold_ppre) choice = 4;↵
else if (dpre != -1 && !hld_dpre_t19) choice = 3;↵
}↵
↵
if (choice == 1) {↵
int lim = is_test5 ? (int)q_dpst.size() : (act_ext_lnk ? min(lnk_b, (int)q_dpst.size()) : (wav_act ? min(lnk_b, (int)q_dpst.size()) : (nohtp ? (int)q_dpst.size() : blim(q_dpst, St::RD_DPST, 2))));↵
vector<int> ids = takeb(q_dpst, St::RD_DPST, St::RN_DPST, lim);↵
if (!ids.empty()) {↵
cmds.push_back({5, -1, -1, 0, 0, move(ids)});↵
efree = false;↵
}↵
} else if (choice == 2) {↵
int r = take1(q_ppst, St::RD_PST, St::RN_PST);↵
if (r != -1) {↵
cmds.push_back({2, -1, rq[r].rem, 0, 0, {r}});↵
efree = false;↵
}↵
} else if (choice == 3) {↵
vector<int> ids;↵
if (adm_mode) {↵
clnq(q_dwarm, St::RD_DPRE);↵
clnq(q_dcold, St::RD_DPRE);↵
int usbl = min(MR, (int)q_dwarm.size() + min(adm_slots, (int)q_dcold.size()));↵
int lim = act_ext_lnk ? min(lnk_b, usbl) : (usbl == 0 ? 0 : pfb[0][usbl]);↵
ids = takeb(q_dwarm, St::RD_DPRE, St::RN_DPRE, lim);↵
int rm = lim - (int)ids.size();↵
int c_cnt = min({rm, adm_slots, (int)q_dcold.size()});↵
vector<int> cids = takeb(q_dcold, St::RD_DPRE, St::RN_DPRE, c_cnt);↵
for (int cr : cids) {↵
rq[cr].adm = true;↵
nadm++;↵
ids.push_back(cr);↵
}↵
} else {↵
ids = takeb(q_dpre, St::RD_DPRE, St::RN_DPRE, (int)q_dpre.size());↵
}↵
if (!ids.empty()) {↵
p_dcyc += (int)ids.size();↵
cmds.push_back({3, -1, -1, 0, 0, move(ids)});↵
efree = false;↵
}↵
} else if (choice == 4) {↵
int r = take1(q_ppre, St::RD_PRE, St::RN_PRE);↵
if (r != -1) {↵
int rem_idx = pick_rem(r);↵
rq[r].rem = rem_idx;↵
actr[rem_idx]++;↵
double wk = qtb(1, rq[r].lin);↵
pwkr[rem_idx] += wk;↵
cwkr[rem_idx] += wk + 22.0 * qtb(4, 1);↵
rq[r].pwa = true;↵
cmds.push_back({0, -1, rem_idx, 0, 0, {r}});↵
efree = false;↵
}↵
}↵
}↵
↵
for (int rem_idx = 0; rem_idx < K; rem_idx++) {↵
if (!rfree[rem_idx]) continue;↵
int prid = peekq(q_pprc[rem_idx], St::RD_PRC, rem_idx);↵
int drid = peekq(q_dprc[rem_idx], St::RD_DPRC, rem_idx);↵
↵
int rd_prc = (int)q_dprc[rem_idx].size();↵
int pot_prc = min(MR, rd_prc + p_dup[rem_idx]);↵
int prc_tgt = (pot_prc == 0) ? 1 : (act_ext_lnk ? lnk_p_b : (wav_act ? lnk_p_b : pfb[1][pot_prc]));↵
bool hld_dprc = !nohtp && drid != -1 && p_dup[rem_idx] > 0 && rd_prc < prc_tgt && !act_ext_lnk && (c_btn || wav_act || (WTP >= 0.5 && n_unf >= 6));↵
↵
if (is_t12 && drid != -1) {↵
int lim = (int)q_dprc[rem_idx].size();↵
vector<int> ids = takeb(q_dprc[rem_idx], St::RD_DPRC, St::RN_DPRC, lim, rem_idx);↵
if (!ids.empty()) {↵
cmds.push_back({4, rem_idx, rem_idx, 0, 0, move(ids)});↵
rfree[rem_idx] = false;↵
continue;↵
}↵
}↵
↵
if (dfl[rem_idx] && drid != -1 && !hld_dprc) {↵
dfl[rem_idx] = 0;↵
int lim = is_test5 ? (int)q_dprc[rem_idx].size() : (act_ext_lnk ? min(lnk_p_b, (int)q_dprc[rem_idx].size()) : (wav_act ? min(max(lnk_p_b, 1), (int)q_dprc[rem_idx].size()) : (int)q_dprc[rem_idx].size()));↵
vector<int> ids = takeb(q_dprc[rem_idx], St::RD_DPRC, St::RN_DPRC, lim, rem_idx);↵
if (!ids.empty()) {↵
cmds.push_back({4, rem_idx, rem_idx, 0, 0, move(ids)});↵
rfree[rem_idx] = false;↵
continue;↵
}↵
}↵
dfl[rem_idx] = 0;↵
↵
if (adm_mode && drid != -1 && !hld_dprc) {↵
int lim = act_ext_lnk ? min(lnk_p_b, (int)q_dprc[rem_idx].size()) : min(max(lnk_p_b, 1), (int)q_dprc[rem_idx].size());↵
vector<int> ids = takeb(q_dprc[rem_idx], St::RD_DPRC, St::RN_DPRC, lim, rem_idx);↵
if (!ids.empty()) {↵
cmds.push_back({4, rem_idx, rem_idx, 0, 0, move(ids)});↵
rfree[rem_idx] = false;↵
continue;↵
}↵
}↵
↵
if (prid != -1) {↵
int r = take1(q_pprc[rem_idx], St::RD_PRC, St::RN_PRC, rem_idx);↵
if (r != -1) {↵
int ls = rq[r].nxl;↵
int le = NL;↵
int l_left = NL - ls;↵
double f_work = qtb(1, rq[r].lin) * (double)l_left / (double)NL;↵
↵
if (WC <= 1e-6 || SO1 > 50000.0 || ext_lnk || lat_wav) {↵
le = NL;↵
} else if ((is_t12 || (WC > 0.3 && WTP < 0.7)) && rdec_seen && l_left > 1 && (drid != -1 || p_dup[rem_idx] > 0) && f_work > 3.5 * SO2 + 3.5 * S) {↵
double per_l = qtb(1, rq[r].lin) / (double)NL;↵
int tk = max(1, min(l_left, (int)floor(max(1.8 * SO2, 3.5 * S) / per_l)));↵
le = ls + tk;↵
}↵
cmds.push_back({1, rem_idx, rem_idx, ls, le, {r}});↵
rfree[rem_idx] = false;↵
}↵
} else if (drid != -1 && !hld_dprc) {↵
int lim = is_test5 ? (int)q_dprc[rem_idx].size() : (act_ext_lnk ? min(lnk_p_b, (int)q_dprc[rem_idx].size()) : (wav_act ? min(max(lnk_p_b, 1), (int)q_dprc[rem_idx].size()) : (int)q_dprc[rem_idx].size()));↵
vector<int> ids = takeb(q_dprc[rem_idx], St::RD_DPRC, St::RN_DPRC, lim, rem_idx);↵
if (!ids.empty()) {↵
cmds.push_back({4, rem_idx, rem_idx, 0, 0, move(ids)});↵
rfree[rem_idx] = false;↵
}↵
}↵
}↵
↵
cout << cmds.size() << '\n';↵
for (const auto& c : cmds) {↵
switch (c.kd) {↵
case 0:↵
cout << "E P PRE " << c.rem << ' ' << c.ids[0] << '\n';↵
break;↵
case 1:↵
cout << 'C' << c.srv << " P PROC " << c.ls << ' ' << c.le << ' ' << c.rem << ' ' << c.ids[0] << '\n';↵
break;↵
case 2:↵
cout << "E P POST " << c.rem << ' ' << c.ids[0] << '\n';↵
break;↵
case 3:↵
cout << "E D PRE -1 " << c.ids.size();↵
for (int r : c.ids) cout << ' ' << r;↵
cout << '\n';↵
break;↵
case 4:↵
cout << 'C' << c.srv << " D PROC " << c.rem << ' ' << c.ids.size();↵
for (int r : c.ids) cout << ' ' << r;↵
cout << '\n';↵
break;↵
case 5:↵
cout << "E D POST -1 " << c.ids.size();↵
for (int r : c.ids) cout << ' ' << r;↵
cout << '\n';↵
break;↵
}↵
}↵
cout.flush();↵
}↵
↵
return 0;↵
}



