#include <stdint.h>
#include <cstdio>
#include <vector>
#include <map>
#include <set>
using namespace std;
/****************************************************************************************************************/
struct Segment {
uint64_t t, size;
Segment *next;
uint32_t id;
int32_t last_d;
const bool will_merge_before(const uint64_t numerator, const uint64_t denominator, const uint64_t fallback) const {
uint64_t factor_this = (this->next->t - this->t) * denominator;
uint64_t factor_other = numerator * (this->size + 1);
if (factor_this != factor_other) return factor_this < factor_other;
return (this->t) < fallback;
}
const bool will_merge_before(const Segment &other) const {
return will_merge_before(other.next->t - other.t, other.size + 1, other.t);
}
const bool will_merge_before(const uint64_t d) const {
return will_merge_before(d, 1, 0);
}
uint64_t square(){ return size * (size + 1) / 2; }
Segment(uint64_t T = 0, int _id = -1):t(T),size(0),id(_id),next(0),last_d(-1){}
};
struct SegmentComparator {
bool operator() (Segment *x, Segment *y) const {
return x->will_merge_before(*y);
}
};
/****************************************************************************************************************/
uint32_t n, m;
vector<uint64_t> T;
vector<uint32_t> D;
vector<Segment*> S;
set<Segment*, SegmentComparator> Q;
map<uint32_t, vector<uint32_t> > M;
vector<uint64_t> result;
int main() {
scanf("%u %u", &n, &m);
T.resize(n+1); D.resize(m);
for (int i=1; i<=n; ++i) scanf("%llu", &T[i]);
for (int i=0; i<m; ++i) scanf("%u", &D[i]);
T[0] = 0; ++n;
result.resize(m);
for (int i=0; i<m; ++i) M[D[i]].push_back(i);
S.resize(n);
for (int i=0; i<n; ++i) {
S[i] = new Segment(T[i], i);
if (i>0) {
S[i-1]->next = S[i];
Q.insert(S[i-1]);
}
}
int64_t current_delay = 0, current_squares = 0, last_d = 0;
while (!M.empty()) {
uint64_t current_d = M.begin()->first;
vector<uint32_t> res_pos = M.begin()->second;
M.erase(M.begin());
int64_t last_squares = current_squares;
while (!Q.empty() && (*Q.begin())->will_merge_before(current_d)) {
Segment *s = *Q.begin();
Segment *rot = s->next;
Q.erase(s);
if (rot->next) Q.erase(rot);
current_delay += (rot->size + 1) * ((s->size + 1)*current_d + s->t - rot->t);
current_squares -= s->square() + rot->square();
s->size += rot->size + 1;
current_squares += s->square();
s->next = rot->next;
if (rot->next) Q.insert(s);
delete rot;
}
current_delay += (last_squares) * (current_d - last_d);
last_d = current_d;
for(int i=0; i<res_pos.size(); ++i) result[res_pos[i]] = current_delay;
}
for(int i=0; i<m; ++i) printf("%llu\n", result[i]);
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | #include <stdint.h> #include <cstdio> #include <vector> #include <map> #include <set> using namespace std; /****************************************************************************************************************/ struct Segment { uint64_t t, size; Segment *next; uint32_t id; int32_t last_d; const bool will_merge_before(const uint64_t numerator, const uint64_t denominator, const uint64_t fallback) const { uint64_t factor_this = (this->next->t - this->t) * denominator; uint64_t factor_other = numerator * (this->size + 1); if (factor_this != factor_other) return factor_this < factor_other; return (this->t) < fallback; } const bool will_merge_before(const Segment &other) const { return will_merge_before(other.next->t - other.t, other.size + 1, other.t); } const bool will_merge_before(const uint64_t d) const { return will_merge_before(d, 1, 0); } uint64_t square(){ return size * (size + 1) / 2; } Segment(uint64_t T = 0, int _id = -1):t(T),size(0),id(_id),next(0),last_d(-1){} }; struct SegmentComparator { bool operator() (Segment *x, Segment *y) const { return x->will_merge_before(*y); } }; /****************************************************************************************************************/ uint32_t n, m; vector<uint64_t> T; vector<uint32_t> D; vector<Segment*> S; set<Segment*, SegmentComparator> Q; map<uint32_t, vector<uint32_t> > M; vector<uint64_t> result; int main() { scanf("%u %u", &n, &m); T.resize(n+1); D.resize(m); for (int i=1; i<=n; ++i) scanf("%llu", &T[i]); for (int i=0; i<m; ++i) scanf("%u", &D[i]); T[0] = 0; ++n; result.resize(m); for (int i=0; i<m; ++i) M[D[i]].push_back(i); S.resize(n); for (int i=0; i<n; ++i) { S[i] = new Segment(T[i], i); if (i>0) { S[i-1]->next = S[i]; Q.insert(S[i-1]); } } int64_t current_delay = 0, current_squares = 0, last_d = 0; while (!M.empty()) { uint64_t current_d = M.begin()->first; vector<uint32_t> res_pos = M.begin()->second; M.erase(M.begin()); int64_t last_squares = current_squares; while (!Q.empty() && (*Q.begin())->will_merge_before(current_d)) { Segment *s = *Q.begin(); Segment *rot = s->next; Q.erase(s); if (rot->next) Q.erase(rot); current_delay += (rot->size + 1) * ((s->size + 1)*current_d + s->t - rot->t); current_squares -= s->square() + rot->square(); s->size += rot->size + 1; current_squares += s->square(); s->next = rot->next; if (rot->next) Q.insert(s); delete rot; } current_delay += (last_squares) * (current_d - last_d); last_d = current_d; for(int i=0; i<res_pos.size(); ++i) result[res_pos[i]] = current_delay; } for(int i=0; i<m; ++i) printf("%llu\n", result[i]); } |
English